guckmalmensch
guckmalmensch

Reputation: 1181

Programmatically change to another tab in SwiftUI

I'm trying to implement in SwiftUI where you press a button in a view on one tab, it changes to another tab. I would do with UIKit:

if [condition...button pressed] {
    self.tabBarController!.selectedIndex = 2
}

But is there an equivalent way to achieve this in SwiftUI?

Upvotes: 42

Views: 26283

Answers (2)

pawello2222
pawello2222

Reputation: 54641

You just need to update a @State variable responsible for the selection. But if you want to do it from a child View you can pass it as a @Binding variable:

struct ContentView: View {
    @State private var tabSelection = 1
    
    var body: some View {
        TabView(selection: $tabSelection) {
            FirstView(tabSelection: $tabSelection)
                .tabItem {
                    Text("Tab 1")
                }
                .tag(1)
            Text("tab 2")
                .tabItem {
                    Text("Tab 2")
                }
                .tag(2)
        }
    }
}
struct FirstView: View {
    @Binding var tabSelection: Int

    var body: some View {
        Button {
            tabSelection = 2
        } label: {
            Text("Change to tab 2")
        }
    }
}

Upvotes: 81

Aivars
Aivars

Reputation: 171

If you like to switch from deeper views you may like to use @AppStorage or @SceenStorage to save the selected tab.

that could look like:

@SceneStorage("selectedView") var selectedView: String?
    
    var body: some View {
        TabView (selection: $selectedView){
            NavigationView {
                TimerView()
            }
            .tag(TimerView.tag)
            .tabItem {
                Image(systemName: "stopwatch.fill")
                Text("Timer")
            }...

And then anywhere in deeper views:

 Button(action: {
                selectedView = TimerView.tag
                    }) {
                        Text("Switch Tab")
                      
                    }

TimerView.tag in example is just constant to do not use strings across the app:

static let tag: String? = "Timer"

SwiftUI will take care of Tab switching as soon as you will update @SceneStorage value and it will save last opened tab in the app as well.

Upvotes: 4

Related Questions