How to Programmatically Navigate Tabs in SwiftUI’s TabView

DevTechie Inc
Dec 7, 2022


Photo by Russ Ward on Unsplash

SwiftUI’s TabView provides a way to present multiple child views in tab based UI and user can switch between tabs by tab selection.

TabViews provide a way to programmatically change tabs. This is useful if you are building app onboarding experience using TabView.

Here is what we will have by the end of this article:

TabView takes selection parameter which is a Binding<Hashable> type, so we can pass any binding variable as long as its conforming to Hashable protocol.

Let’s build a simple app onboarding screen to learn programmatic tab selection.

We will start with StepsView, which will be the steps we want to show our users. This view will take title, subtitle to show info about he app. This view will also take two binding properties, selectedIndex(to capture and increase page index) and showHome(to show home screen when user is at the last step)

struct StepsView: View {
    var title: String
    var subtitle: String
    @Binding var selectedIndex: Int
    @Binding var showHome: Bool
    
    var body: some View {
        NavigationStack {
            ZStack(alignment: .bottomTrailing) {
                VStack {
                    Text(title)
                        .font(.largeTitle)
                        .foregroundColor(.primary)
                    
                    Text(subtitle)
                        .font(.title3)
                        .foregroundColor(.secondary)
                }
                .frame(maxHeight: .infinity)
                
                Button {
                    withAnimation {
                        if selectedIndex >= 2 {
                            showHome.toggle()
                        } else {
                            selectedIndex += 1
                        }
                    }
                } label: {
                    Image(systemName: "arrow.right.circle.fill")
                        .font(.largeTitle)
                }}
            .navigationTitle("DevTechie.com")
        }
    }
}
We also need a home view which is very simple view:

struct HomeView: View {
    var body: some View {
        Text("Welcome home, DevTechie!")
            .font(.largeTitle)
    }
}
Now, we will create our content view, which will host HomeView and TabView(for Steps). We will have two State properties for this view, selectedTab(to programmatically select and move tabs), showHome(to show HomeView).

Note that our TabView will have pageStyle with indexDisplayMode marked as never.

struct ContentView: View {
    @State private var selectedTab = 0
    @State private var showHome = false
    
    var body: some View {
        if showHome {
            HomeView()
        } else {
            TabView(selection: $selectedTab) {
                StepsView(title: "Learn SwiftUI 4", subtitle: "Learn SwiftUI by building apps", selectedIndex: $selectedTab, showHome: $showHome)
                    .tabItem {
                        Label("Course1", systemImage: "seal")
                    }
                    .tag(0)
                
                StepsView(title: "Photo Gallery App", subtitle: "Build Photo Gallery App", selectedIndex: $selectedTab, showHome: $showHome)
                    .tabItem {
                        Label("Course2", systemImage: "app")
                    }
                    .tag(1)
                
                StepsView(title: "Disney Plus Clone", subtitle: "Build DisneyPlus Clone in SwiftUI", selectedIndex: $selectedTab, showHome: $showHome)
                    .tabItem {
                        Label("Course3", systemImage: "octagon")
                    }
                    .tag(2)
            }
            .tabViewStyle(.page(indexDisplayMode: .never))
        }
    }
}
Notice the use of tag modifier. This modifier helps SwiftUI identify each tab uniquely and enables programmatic tab navigation.
Build and run:

With that we have reached the end of this article. Thank you once again for reading. Don’t forget to follow 😍. Also subscribe our newsletter at https://www.devtechie.com