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.
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!
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.