How to create tabs in SwiftUI

Use TabView to create the tab in SwiftUI. This article explains that how to create tabs in SwiftUI.

TOC

Basic Structure

The TabView is used in the following structure.

struct ContentView: View {
    var body: some View {
        TabView {
            // --- START ---
            // The view in the tab.
            Text("Tab 1") // The tab item root view.
                .tabItem {
                    // The view displayed in the label
                    Text("Item 1")
                }
            // --- END ---

            // --- START ---
            // The view in the tab.
            Text("Tab 2") // The tab item root view.
                .tabItem {
                    // The view displayed in the label
                    Text("Item 2")
                }
            // --- END ---

            // --- START ---
            // The view in the tab.
            Text("Tab 3") // The tab item root view.
                .tabItem {
                    // The view displayed in the label
                    Text("Item 3")
                }
            // --- END ---

            // As above, repeat from "START" to "END" for each tab items.
        }
    }
}

About TabView

The TabView is a container view of SwiftUI, It display the sub view as a tab item.

About tabItem modifier

The tabItem modifier creates the label of the tab item.

Preview for each platforms

Run above code, it displays as follows on iPhone.

View on iPhone
View on iPhone

It displays as follows on iPad.

View on iPad
View on iPad

It displays as follows on macOS.

View on macOS
View on macOS

How to create labels

Use tabItem modifier to create the tab labels. The displayed view is specified to the argument. The argument is a closure, so writing it in the syntax of a trailing closure is like defining a subviews.

Text only labels

Text only labels are created using Text, as in the sample code above.

.tabItem {
    Text("Label Title")
}

Icon only labels

Icon only labels are created using Image instead of Text.

import SwiftUI

struct ContentView: View {
    var body: some View {
        TabView {
            Text("Tab 1")
                .tabItem {
                    Image(systemName: "folder")
                }
            Text("Tab 2")
                .tabItem {
                    Image(systemName: "tray")
                }
            Text("Tab 3")
                .tabItem {
                    Image(systemName: "externaldrive")
                }
        }
    }
}
Display on iPhone
Display on iPhone

However, macOS apps can’t display the images in the labels, so nothing is displayed.

Display on macOS
Display on macOS

Labels combining icons and text

To create a label that combines an icon and text, use VStack to display the Image and Text side by side, as you would when defining any other view.

import SwiftUI

struct ContentView: View {
    var body: some View {
        TabView {
            Text("Tab 1")
                .tabItem {
                    VStack {
                        Image(systemName: "folder")
                        Text("Folder")
                    }
                }
            Text("Tab 2")
                .tabItem {
                    VStack {
                        Image(systemName: "tray")
                        Text("Tray")
                    }
                }
            Text("Tab 3")
                .tabItem {
                    VStack {
                        Image(systemName: "externaldrive")
                        Text("External Drive")
                    }
                }
        }
    }
}
Display on iPhone
Display on iPhone

Note that even if you use HStack to display images and text horizontally, they will line up vertically. Only vertical orientation is supported.

Also, macOS apps cannot display images, only text.

Display on macOS
Display on macOS

Margins around tabs

For macOS applications, use the padding modifier to add margins, otherwise the window frame and tab frame will be adjacent to each other.

struct ContentView: View {
    var body: some View {
        TabView {
            Text("Tab 1")
                .tabItem {
                    VStack {
                        Image(systemName: "folder")
                        Text("Folder")
                    }
                }
            Text("Tab 2")
                .tabItem {
                    VStack {
                        Image(systemName: "tray")
                        Text("Tray")
                    }
                }
            Text("Tab 3")
                .tabItem {
                    VStack {
                        Image(systemName: "externaldrive")
                        Text("External Drive")
                    }
                }
        }
        #if os(OSX)
            .padding()
        #endif
    }
    
}

As above, #if os(OSX) specifies to do .padding() only when it is a macOS app.

Display on macOS
Display on macOS

Introduction to my book

I wrote the book titled “基礎から学ぶ SwiftUI”. This book explains about the basic view of SwiftUI not only TabView.

For more information, please see the above article.

Let's share this post !

Author of this article

Akira Hayashiのアバター Akira Hayashi Representative, Software Engineer

I am an application developer loves programming. This blog is a tech blog, its articles are learning notes. In my work, I mainly focus on desktop and mobile application development, but I also write technical books and teach seminars. The websites of my work and books are here -> RK Kaihatsu.

TOC