跳转至
Structure

TabView

A parent view for tab-style navigation.

Declaration

struct TabView<SelectionValue, Content> : View where SelectionValue : Hashable, Content : View

Overview

TabView is a container view that provides tab-style navigation for its child views.

Tab-bar based navigation

Place child views in a TabView and apply tabItem(_:) to each child for tab-bar style navigation.

struct ContentView: View {
    var body: some View {
        TabView {
            Text("Bananas 🍌🍌")
                .tabItem {
                    Image(systemName: "1.circle.fill")
                    Text("🍌🍌")
                }
            Text("Apples 🍏🍏")
                .tabItem {
                    Image(systemName: "2.square.fill")
                    Text("🍏🍏")
                }
            Text("Peaches 🍑🍑")
                .tabItem {
                    Image(systemName: "3.square.fill")
                    Text("🍑🍑")
                }
        }
        .font(.headline)
    }
}
A gif that jumps between the three text views, "Bananas 🍌🍌", "Apples 🍏🍏", and "Peaches 🍑🍑", within a TabView by clicking the corresponding symbols on the tab-bar: each tab bar item is a filled circle with the page number above the two matching emojis corresponding to the those in the text views.

Page-style navigation

In iOS 14+ only, you can place child views in a TabView with a View.tabViewStyle(PageTabViewStyle()) attached to the TabView for a page-style style navigation.

The following example creates a paginated view with the three Text child views as individual pages.

struct ContentView: View {
    var body: some View {
        TabView {
            Text("Bananas 🍌🍌")
            Text("Apples 🍏🍏")
            Text("Peaches 🍑🍑")
        }
        .foregroundColor(Color.white)
        .background(Color.yellow)
        .tabViewStyle(PageTabViewStyle())
    }
}
A gif that flips between the three pages, each containing a text item, in a tabview whilst displaying the page indicators at the bottom of the view.

TabView also supports dynamically loading pages. The example above can be re-expressed as the following:

struct ContentView: View {
    @State var items = ["Bananas 🍌🍌", "Apples 🍏🍏", "Peaches 🍑🍑"]

    var body: some View {
        TabView {
            ForEach(items, id: \.self) {
                Text($0)
                    .foregroundColor(Color.white)
            }
        }
        .tabViewStyle(PageTabViewStyle())
        .background(Color.black)
    }
}
A gif that flips between the three dynamically loading pages, each containing a text item, in a tabview whilst displaying the page indicators at the bottom of the view.

This example supports loading a dynamic list of pages from items.

A page-styled TabView will add a row of page indicator(s) at the bottom of the container by default. If tabItem(_:) is used, these indicators each take the form of the corresponding tab item's primary image. If not - these page indicators resort to system defaults.

To disable page indicators altogether, apply a PageTabViewStyle using tabViewStyle(_:), like so:

struct ContentView: View {
    @State var items = ["Bananas 🍌🍌", "Apples 🍏🍏", "Peaches 🍑🍑"]

    var body: some View {
        TabView {
            ForEach(items, id: \.self) { item in
                Text(item)
            }
        }
        .background(Color.yellow)
        .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
    }
}
A gif that flips between the three dynamically loading pages, each containing a text item, in a tabview without displaying page indicators.

Handling tab-selection

TabView provides the ability to observe and/or set the active tab selection via its initializer init(selection:content:), and the modifier tag(_:).

Here is an example that writes tab selection to a state variable:

struct ContentView: View {
    enum TabItem {
        case bananas, apples, peaches
    }
    @State var selectedItem = TabItem.bananas

    var body: some View {
        TabView(selection: $selectedItem) {
            Text("Bananas 🍌🍌")
                .tabItem {
                    Image(systemName: "1.circle.fill")
                    Text("🍌🍌")
                }
                .tag(TabItem.bananas)

            Text("Apples 🍏🍏")
                .tabItem {
                    Image(systemName: "2.square.fill")
                    Text("🍏🍏")
                }
                .tag(TabItem.apples)

            Text("Peaches 🍑🍑")
                .tabItem {
                    Image(systemName: "3.square.fill")
                    Text("🍑🍑")
                }
                .tag(TabItem.peaches)
        }
    }
}
A gif that jumps between the three children in a TabView by clicking the various symbols on the tab-bar; the tab selection is written to a state variable.

In this example, each tab item is assigned a unique tag using the tag(_:) view modifier. TabView in turn takes a binding to the tab selection, $selectedItem, and updates it whenever a new tab is selected. $selectedItem in turn can also be used to programmatically control tab-selection, as bindings work bidirectionally.

Note that tag(_:) accepts any Hashable value. An enum was used in the previous example, but it could've just as easily been a String or an Int.

For example, the following uses a traditional 0-based tab indexing:

struct ContentView: View {
    @State var selectedItem = 0

    var body: some View {
        TabView(selection: $selectedItem) {
            Text("Bananas 🍌🍌")
                .tag(0)

            Text("Apples 🍏🍏")
                .tag(1)

            Text("Peaches 🍑🍑")
                .tag(2)
        }
    }
}
A gif that jumps between the three children in a TabView without icons in the tab-bar.

Availability

iOS 13.0+

macOS 10.15+

tvOS 13.0+

watchOS 7.0+

Topics


Instance Property

body The content and behavior of the view.


Initializer

init(content:) Creates a TabView from only a view builder of pages.

init(selection:content:) Creates a TabView from a selection and a view builder of pages.


Type Alias

Body The type of view representing the body of this view.