5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

TabViewのtabItemのタップを検知して、ページトップに遷移する方法

Posted at

はじめに

UIKitのTabBarControllerでは、tabItemのタップを処理するdelegateメソッドがあったが、SwiftUIのTabViewでの実装方法を検証した。なお、iOS13+を前提(SwiftUI2.0で追加されたAPIは使わない)とする。

検証環境

  • Xcode 12.4
  • iOS14.4 / iOS13.5

実装

TabView
import SwiftUI

struct TabBar_View: View {
    
    @State var selection: Int = 0
    // タブ内の表示を先頭にスクロールさせるため、インデックスを保持
    @State var advViewIndex: Int = 0
    
    var body: some View {
        
        // MARK: TabItemのタップを検知し、メソッドを実行するための変数。TabViewの selection に設定
        let selectedTab = Binding<Int>(get: {
              self.selection
          }, set: {
            if $0 == self.selection {
                self.scrollToTop()
            }
            self.selection = $0
          })

        
        TabView(selection: selectedTab) {
            HT_View()
                .tabItem {
                    Image("Home_Icon")
                        .renderingMode(.template)
                    Text("Home")
                }
                .tag(0)
            Adv_View(index: $advViewIndex)
                .tabItem {
                    Image("Event_Icon")
                        .renderingMode(.template)
                    Text("Event")
                }
                .tag(1)
            Room_List()
                .tabItem {
                    Image("Room_Icon")
                        .renderingMode(.template)
                    Text("Room")
                }
                .tag(2)
            #if DEBUG
            Dummy()
                .tabItem {
                    Image(systemName: "gear")
                    Text("Dummy")
                }
                .tag(3)
            #endif
        }.accentColor(Color.primary)
        /* MARK: iOS14では、.id を設定すると、NavigationViewを持つ画面に遷移する際にクラッシュ
         * 原因不明。HT_ViewもNavigationView を持っていて、起動時にはクラッシュしないが、他のタブに移動後、戻ってくるとクラッシュした
         * iOS14+を対象とする場合は、WindowGroup の利用によるリファクタリングも検討する
         */
        //.id(selectedTab)
    }
    
    // 表示中のタブのTabItemをタップした時にページの先頭に戻る処理
    private func scrollToTop() {
        if self.selection == 1 {
            // アニメーションを設定しないと、いきなり先頭に戻り違和感がある。iOS13ではアニメーションがわかりずらいが、そのままにしている
            withAnimation() {
                self.advViewIndex = 0
            }
        }
    }
}

参考リンク

Swiftui TabBar: Action for tapping TabItem of currently selected Tab to reset view

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?