'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?



Solution 1:[1]

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(action: {
            self.tabSelection = 2
        }) {
            Text("Change to tab 2")
        }
    }
}

Solution 2:[2]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Aivars