matthias_code
matthias_code

Reputation: 1013

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?

Upvotes: 21

Views: 7716

Answers (2)

Meyssam
Meyssam

Reputation: 694

UPDATE 2024

Apple just released iOS 18 Beta 2 two hours ago, in which this feature got implemented. The release notes say:

New Features

When using a TabView, tapping on the current tab now pops any embedded navigation stack. (50924017)

I've tested this an can confirm, that this works independently from the compiler that was used to distribute the app. It works out of the box and for apps that were compiled before iOS 18.

Upvotes: 3

Asperi
Asperi

Reputation: 257701

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)
        }
    }
}

Upvotes: 31

Related Questions