Search code examples
swiftswiftui

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


The app I am working on is based around a TabBar, and when I am on a tab I want to be able to click the tabItem again to reset the view, similar to how Twitter does it in their tabBar.

I do not know how to recognize that action though. Adding a button to the TabItem is not working, addidng a tapGesture modifier isn't either, and I can't think of anything else I could try.

struct ContentView: View {
  var body: some View {
    TabView() {
      Text("Tab 1")
        .tabItem {
          Image(systemName: "star")
            .onTapGesture {
              print("Hello!")
            }
          Text("One")
        }
        .tag(0)
      
      Text("Tab 2")
        .tabItem {
          Button(action: {
            print("Hello!")
          }, label: {
            Image(systemName: "star.fill")
          })
        }
        .tag(1)
    }
  }
}

It should't automatically reset when opening the tab again, which I have seen discussed elsewhere, but when tapping the tabItem again.

What other things am I possibly missing here?


Solution

  • Here is possible solution - inject proxy binding around TabView selection state and handle repeated tab tapped before bound value set, like below.

    Tested with Xcode 12.1 / iOS 14.1

    struct ContentView: View {
        @State private var selection = 0
        
        var handler: Binding<Int> { Binding(
            get: { self.selection },
            set: {
                if $0 == self.selection {
                    print("Reset here!!")
                }
                self.selection = $0
            }
        )}
        
        var body: some View {
            TabView(selection: handler) {
                Text("Tab 1")
                    .tabItem {
                        Image(systemName: "star")
                        Text("One")
                    }
                    .tag(0)
                
                Text("Tab 2")
                    .tabItem {
                        Image(systemName: "star.fill")
                    }
                    .tag(1)
            }
        }
    }