Working with TabView in SwiftUI iOS 01.03.2022

SwiftUI navigation forms two styles: flat and hierarchical. SwiftUI uses TabView to implement a flat hierarchy. A tab bar appears at the bottom of an app screen and let users quickly switch between different functions of an app.

SwiftUI's TabView is a container view and consist of a range of child views and is similar to UIKit's UITabBarController. It provides an easy and intuitive way to present multiple views to the user and allow them to easily navigate between each of those views. It allows the user to navigate between different child views either by selecting tab items located in a tab bar or, when using the page view tab style, by making swiping motions.

The following code will display an app with two tabs

TabView {
    Text("Item 1").font(.system(size: 30, weight: .bold))
    .tabItem {
        Image(systemName: "house")
        Text("Tab 1")
    }

    Text("Item 2").font(.system(size: 30, weight: .bold))
    .tabItem {
        Image(systemName: "house.fill")
        Text("Tab 2")
    }
    .badge(7)
}

This TabView includes two parts

  • Text("Item 1"): this is the view that will be displayed when tapping on this tab item.
  • tabItem {}: this is the tab item that you can style with an image and text.

However, most apps would require the developer to display more information on each tab.

Host view

struct ContentView: View {
    var body: some View {
        TabView {
            ItemsView()
            .tabItem {
                Image(systemName: "list.star")
                Text("Home")
            }
            PhotoView()
            .tabItem {
                Image(systemName:"photo")
                Text("Photo")
            }
        }
    }
}

View for Tab 1

struct ItemsView: View {
    let items = ["The Godfather", "The Dark Knight"]    
    var body: some View {
        NavigationView {
            List {
                ForEach(items, id: \.self){ item in
                Text(item).padding()
            }
        }.navigationBarTitle("Items", displayMode: .inline)
    }
}

View for Tab 2

struct PhotoView: View {
    var body: some View {
        NavigationView {
            VStack {
                Image(systemName:"photo")
                Text("Photo")
            }
        }.navigationBarTitle("Photo")
    }
}

In iOS 14, SwiftUI's TabView can action as a UIPageViewController. You can allow swiping through multiple screens using paging dots. To implement this, add a .tabViewStyle() modifier to the TabView and pass the PageTabViewStyle() as follows:

struct ContentView: View {
    var body: some View {
        TabView {
            Text("Item 1")
            Text("Item 2")
            Text("Item 3")
        }
        .font(.largeTitle)
        .tabViewStyle(PageTabViewStyle())
        //.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always)
    }
}

Customizing the Tab Bar

By default, the color of the tab bar item is set to blue. You can change its color by attaching the .accentColor modifier to TabView like this

TabView {
}
.accentColor(.green)

However, if you are targeting on iOS 15 and above, then use the tint(_:) view modifier instead

 
TabView {
}
.tint(.green)

Yet the SwiftUI framework doesn't have a built-in modifier for changing the tab bar's background color. But you may use the appearance API of UIKit like below

.onAppear() {
    UITabBar.appearance().barTintColor = .green
}