SwiftUI · · 4 min read

Customizing Toolbar and Navigation Bar in SwiftUI

Customizing Toolbar and Navigation Bar in SwiftUI

The Toolbar API has been available for a considerable period, having been introduced with the release of iOS 14. It was a valuable addition to the SwiftUI framework, enabling developers to incorporate menu items in the navigation and bottom bars. In iOS 16, Apple unveiled additional modifiers to further enhance the customization of toolbars and provide developers with greater control over their appearance.

In this tutorial, let me show you how to work with toolbars and manage its customizations.

Using the Toolbar Modifier to Populate Navigation Bar Items

Whether you need to populate items in navigation bars or toolbars, you can utilize the .toolbar modifier to achieve this objective. Here is an example:

struct ContentView: View {
    var body: some View {
        NavigationStack {
            List(1..<10, id: \.self) { index in
                NavigationLink("Item \(index)") {
                    Image("legomen")
                        .resizable()
                        .ignoresSafeArea()
                }
            }

            .navigationTitle("Toolbar Demo")

            .toolbar {
                Button {
                    // action
                } label: {
                    Image(systemName: "plus")
                }

                Button {
                    // action
                } label: {
                    Image(systemName: "square.and.arrow.up")
                }

            }
        }

    }
}

Inside the closure of toolbar, we create a pair of standard buttons using system images. Without explicitly specifying the placement of the buttons, SwiftUI automatically positions them in the top-right corner of the navigation bar.

swiftui-toolbar-navigation-items

Using ToolbarItem

If you need to add more items to the navigation bar, you can continue to add buttons in the toolbar closure. However, if you want to control the placement of the items, you can provide a collection of views with each view wrapped in a ToolbarItem. Below is an example:

.toolbar {
    ToolbarItem(placement: .principal) {
        Image(systemName: "person.crop.circle")
    }

    ToolbarItem(placement: .topBarLeading) {
        Button {
            // action
        } label: {
            Image(systemName: "line.3.horizontal")
        }
    }

    ToolbarItem(placement: .topBarTrailing) {
        Button {
            // action
        } label: {
            Image(systemName: "plus")
        }
    }

    ToolbarItem(placement: .topBarTrailing) {
        Button {
            // action
        } label: {
            Image(systemName: "square.and.arrow.up")
        }
    }

    ToolbarItem(placement: .bottomBar) {
        Image(systemName: "folder")
    }

    ToolbarItem(placement: .bottomBar) {
        Image(systemName: "message")
    }

    ToolbarItem(placement: .status) {
        Button {

        } label: {
            Text("Hide Navigation")
        }
        .buttonStyle(.borderedProminent)
        .controlSize(.extraLarge)
    }
}

Each ToolbarItem enables you to define the position of the item by utilizing the placement parameter. To add items in the navigation bar, you can specify the following values:

  • .topBarLeading – Places the item in the leading edge of the top bar.
  • .topBarTrailing – Places the item in the trailing edge of the top bar.
  • .principle – Places the item in the principal item section,which is the center of the navigation bar.

To add items in the bottom bar, you can set the value to .bottomBar and .status:

  • .bottomBar – Places the item in the bottom toolbar.
  • .status – In iOS and iPadOS, the system places status items in the center of the bottom toolbar.
swiftui-toolbar-bottom-bar

How to Hide the Navigation Bar and Bottom Bar

Starting from iOS 16, the toolbar modifier offers developers the ability to manage the visibility of toolbars, including the navigation bar and bottom bar. To hide the navigation bar, you can insert the toolbar modifier inside NavigationStack like this:

.toolbar(.hidden, for: .navigationBar)

If you want to provide an option for users to hide/show the navigation bar, you can declare a state variable like below:

@State private var showNavBar = true

Then you can update the .toolbar modifier like this:

.toolbar {

      .
      .
      .

      ToolbarItem(placement: .status) {
        Button {
            showNavBar.toggle()
        } label: {
            Text(showNavBar ? "Hide Navigation" : "Show Navigation")
        }
        .buttonStyle(.borderedProminent)
        .controlSize(.extraLarge)
    }
}
.toolbar(showNavBar ? .visible : .hidden, for: .navigationBar)
.animation(.easeInOut, value: showNavBar)

To hide the visibility of the bottom bar, you can replace .navigationBar with .bottomBar. Here is an example:

.toolbar(.hidden, for: .bottomBar)

Controlling the Visibility of Toolbar Background

SwiftUI offers another modifier called toolbarBackground for developers to control the visibility of the toolbar background. To make the navigation bar background transparent, you can set the value of toolbarBackground to .hidden:

.toolbarBackground(.hidden, for: .navigationBar)

To make the background visible, you can set the value to .visible. Here is an example:

List(1..<10, id: \.self) { index in
    NavigationLink("Item \(index)") {
        Image("legomen")
            .resizable()
            .ignoresSafeArea()
            .toolbarBackground(.visible, for: .navigationBar)
    }
}

After making the code changes, you should see a navigation bar with a blurred background when navigating to the detail view.

swiftui-toolbar-background

Toolbar Color Scheme

You can exert additional control over the color scheme of the navigation bar or bottom bar by employing the toolbarColorScheme modifier. For instance, to apply dark mode to the navigation bar of the detail view, you can apply the toolbarColorScheme modifier to the Image view as demonstrated below:

.toolbarColorScheme(.dark, for: .navigationBar)

Now, when you navigate to the detail view, the navigation bar changes to dark mode.

swiftui-toolbar-background-dark-mode

Summary

Throughout this tutorial, we have covered the fundamentals of the Toolbar APIs and explored how to populate items in toolbars. As the SwiftUI framework continues to evolve, it offers developers an expanded range of functionalities to customize the appearance of navigation and bottom bars. These advancements enable developers to create more visually appealing and tailored user interfaces in their SwiftUI apps.

If you want to learn more about SwiftUI, you can check out our Mastering SwiftUI book. It’s now fully updated for Xcode 15 and iOS 17.

Read next