SwiftUI TabView is a view which let’s us create Tab based UI(similar to UITabBarController). Tabs are displayed at the bottom of the window and we can select/display different views. Each tab in TabView is associated with a View and when user selects a specific tab, corresponding view shows up replacing the previous view.
Let’s start with a simple example.
struct ContentView: View {
var body: some View {
TabView {
}
}
}
This creates the bottom tab bar view.
Next, we will add views to TabView. We will add three Color views.
struct ContentView: View {
var body: some View {
TabView {
Color.blue
.edgesIgnoringSafeArea(.top)
Color.orange
.edgesIgnoringSafeArea(.top)
Color.mint
.edgesIgnoringSafeArea(.top)
}
}
}
If you build and run, you will realize that by clicking leading, middle and trailing points on tab bar, the tab will change and view will reflect the change:
But this is not a vary useful UI as our users wouldn’t know where to click or what to do so lets add label to these tabs. We do that by adding tabItem modifier which takes a label as parameter. Let’s update our code with following:
struct ContentView: View {
var body: some View {
TabView {
Color.blue
.edgesIgnoringSafeArea(.top)
.tabItem {
Image(systemName: "1.circle")
Text("Tab 1")
}
Color.orange
.edgesIgnoringSafeArea(.top)
.tabItem {
Image(systemName: "2.circle")
Text("Tab 2")
}
Color.mint
.edgesIgnoringSafeArea(.top)
.tabItem {
Image(systemName: "3.circle")
Text("Tab 3")
}
}
}
}
TabViewStyle
Default TabView style is to display tabs at the bottom. We can change the default style to page style with .tabViewStylemodifier
struct ContentView: View {
var body: some View {
TabView {
Color.blue
.edgesIgnoringSafeArea(.top)
.tabItem {
Image(systemName: "1.circle")
Text("Tab 1")
}
Color.orange
.edgesIgnoringSafeArea(.top)
.tabItem {
Image(systemName: "2.circle")
Text("Tab 2")
}
Color.mint
.edgesIgnoringSafeArea(.top)
.tabItem {
Image(systemName: "3.circle")
Text("Tab 3")
}
}
.tabViewStyle(.page)
}
}
We can change the experience to a full screen view by adding edgesIgnoringSafeArea(.vertical) modifier.
struct ContentView: View {
var body: some View {
TabView {
Color.blue
.edgesIgnoringSafeArea(.vertical)
.tabItem {
Image(systemName: "1.circle")
Text("Tab 1")
}
Color.orange
.edgesIgnoringSafeArea(.vertical)
.tabItem {
Image(systemName: "2.circle")
Text("Tab 2")
}
Color.mint
.edgesIgnoringSafeArea(.vertical)
.tabItem {
Image(systemName: "3.circle")
Text("Tab 3")
}
}
.tabViewStyle(.page)
.edgesIgnoringSafeArea(.vertical)
}
}
We can hide or show page index view with the help of page(indexDisplayMode:) function as shown below:
struct ContentView: View {
var body: some View {
TabView {
Color.blue
.edgesIgnoringSafeArea(.vertical)
.tabItem {
Image(systemName: "1.circle")
Text("Tab 1")
}
Color.orange
.edgesIgnoringSafeArea(.vertical)
.tabItem {
Image(systemName: "2.circle")
Text("Tab 2")
}
Color.mint
.edgesIgnoringSafeArea(.vertical)
.tabItem {
Image(systemName: "3.circle")
Text("Tab 3")
}
}
.tabViewStyle(.page(indexDisplayMode: .never))
.edgesIgnoringSafeArea(.vertical)
}
}
IndexViewStyle
indexViewStyle modifier helps us style the page indicator background. For example, for the page style tabView if we remove tabItem modifier from the view, our view will look like this:
struct ContentView: View {
var body: some View {
TabView {
Color.blue
.edgesIgnoringSafeArea(.vertical)
Color.orange
.edgesIgnoringSafeArea(.vertical)
Color.mint
.edgesIgnoringSafeArea(.vertical)
}
.tabViewStyle(.page(indexDisplayMode: .always))
.edgesIgnoringSafeArea(.vertical)
}
}
Notice that we have 3 dots at the bottom of the screen to display pages. If you tap and hold on those dots a capsule as a background appears. We can control the appearance of that capsule background with the help of indexViewStylemodifier.
Let’s add the modifier and set background display mode to be always:
struct ContentView: View {
var body: some View {
TabView {
Color.blue
.edgesIgnoringSafeArea(.vertical)
Color.orange
.edgesIgnoringSafeArea(.vertical)
Color.mint
.edgesIgnoringSafeArea(.vertical)
}
.tabViewStyle(.page(indexDisplayMode: .always))
.indexViewStyle(.page(backgroundDisplayMode: .always))
.edgesIgnoringSafeArea(.vertical)
}
}
Other options are
.interactive which is the default and in this case, background only appears when user taps and holds on the pager.
.never meaning the background is never shown
.automatic meaning the background display will be determined by the system based on the context its being shown.
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