NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

How to embed views in a tab bar using TabView

Paul Hudson    @twostraws   

Updated for Xcode 14.2

SwiftUI’s TabView provides an equivalent to UITabBarController, allowing us to let the user switch between several active views using a bar at the bottom of the screen.

In its basic form, you should provide each item with an image and title, optionally also adding a tag if you want to control which tab is active programmatically. For example, this creates two views with different images, titles, and tags:

struct ContentView: View {    
    var body: some View {
        TabView {
            Text("First View")
                .padding()
                .tabItem {
                    Image(systemName: "1.circle")
                    Text("First")
                }
                .tag(1)
            Text("Second View")
                .padding()
                .tabItem {
                    Image(systemName: "2.circle")
                    Text("Second")
                }
                .tag(2)
        }
    }
}

Download this as an Xcode project

Rather than specifying text and image separately, you can also use a Label view to combine them together:

struct ContentView: View {
    var body: some View {
        TabView {
            Text("First View")
                .padding()
                .tabItem {
                    Label("First", systemImage: "1.circle")
                }
                .tag(1)

            Text("Second View")
                .padding()
                .tabItem {
                    Label("Second", systemImage: "2.circle")
                }
                .tag(2)
        }
    }
}

Download this as an Xcode project

Tip: From iOS 15 you should not explicitly request the filled variant of SF Symbols icons, because the system will automatically use them as appropriate.

If you add tags, you can programmatically control the active tab by modifying the tab view’s selection. In this example I’ve made the content of each tab a button that changes view, which is done by adding some new state to track which tab is active, then attaching that to the selection value of the TabView:

struct ContentView: View {
    @State var selectedView = 1

    var body: some View {
        TabView(selection: $selectedView) {
            Button("Show Second View") {
                selectedView = 2
            }
            .padding()
            .tabItem {
                Label("First", systemImage: "1.circle")
            }
            .tag(1)

            Button("Show First View") {
                selectedView = 1
            }
            .padding()
            .tabItem {
                Label("Second", systemImage: "2.circle")
            }
            .tag(2)
        }
    }
}

Download this as an Xcode project

The tags for your tabs can whatever you want, as long as the data type conforms to Hashable. Integers might work well, but if you’re going to do any meaningful programmatic navigation you should make sure you put the tags somewhere central such as a static property inside the view. This allows you to share the value in many places, reducing the risk of mistakes.

Hacking with Swift is sponsored by Essential Developer

SPONSORED From March 20th to 26th, you can join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer!

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Similar solutions…

BUY OUR BOOKS
Buy Pro Swift Buy Pro SwiftUI Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

Average rating: 3.8/5

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.