Programmatically Linking to Another Tab from Any Child View in SwiftUI

In SwiftUI, you can trigger a change of tab from any element of any view by using the selection tags and setting a binding with child views.

How to programmatically link to another tab from any child view in SwiftUI

Tab Selection 

Set the state for tab selection and apply the tag to each tab item. By default, it's set to the first tab.

struct TabBar: View {
    @State var tabSelection = 1

    var body: some View {
        TabView(selection: $tabSelection) {
            ContentView()
                .tabItem {
                    Image(systemName: "square.grid.2x2.fill")
                    Text("Home") }
                .tag(1)

            SecondView()
                .tabItem {
                    Image(systemName: "rectangle.stack.fill")
                    Text("Settings")
                }
                .tag(2)
        }
    }
}

..

Child View with Binding In your View, set a Binding that will synchronize to the Tab Bar's tabSelection.

// ContentView
@Binding var tabSelection: Int

..

You will need to set the default tabSelection value.

ContentView(tabSelection: .constant(1))

..

Also, when calling from the Tab Bar, the binding needs to be done.

// TabBar
ContentView(tabSelection: $tabSelection)

..

Now, you can change the tab from any button, link or gesture.

// ContentView
Text("Change tab")
	.onTapGesture {
		tabSelection = 2
	}

..

Output:

In the final project, you will have 3 views: TabBar, ContentView and SecondView.

In TabBar.swift, set the tab selection and pass the Binding to the child view.

struct TabBar: View {
    @State var tabSelection = 1

    var body: some View {
        TabView(selection: $tabSelection) {
            ContentView(tabSelection: $tabSelection)
                .tabItem {
                    Image(systemName: "square.grid.2x2.fill")
                    Text("Home") }
                .tag(1)

            SecondView()
                .tabItem {
                    Image(systemName: "rectangle.stack.fill")
                    Text("Settings")
                }
                .tag(2)
        }
    }
}

..

In ContentView.swift, set the Binding that syncs with the TabBar. Also, we're setting a tap gesture that allows us to change the tab.

struct ContentView: View {
    @Binding var tabSelection: Int

    var body: some View {
        Text("Change tab")
            .onTapGesture {
                tabSelection = 2
            }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(tabSelection: .constant(1))
    }
}

..

In SecondView.swift, we have a basic screen.

struct SecondView: View {
    var body: some View {
        Text("Second View")
    }
}

..


Comments