NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

How to let users customize toolbar buttons

Paul Hudson    @twostraws   

Updated for Xcode 14.2

SwiftUI’s toolbar allows the user to customize any toolbar items we allow, and it takes five small steps:

  1. Give your toolbar a unique, stable identifier string.
  2. Give each customizable toolbar item a unique, stable identifier string.
  3. Place customizable buttons in the .secondaryAction category.
  4. Decide which buttons should be visible by default.
  5. Enable Editor mode for your toolbar, so that all the secondary actions become toolbar buttons.

The “unique, stable” identifier requirement matters, because this is what SwiftUI uses to remember the user’s settings – “toolbar X has button A, then C, then F.”

Note: Only some platforms support toolbar customization. This API will work best on iPadOS and macOS, where complicated toolbars are more common.

Here’s a code sample showing all those steps:

NavigationStack {
    Text("SwiftUI")
        .navigationTitle("Welcome")
        .toolbar(id: "options") {
            // this is a primary action, so will always be visible
            ToolbarItem(id: "settings", placement: .primaryAction) {
                Button("Settings") { }
            }

            // this is a standard secondary action, so will be customizable
            ToolbarItem(id: "help", placement: .secondaryAction) {
                Button("Help") { }
            }

            // another customizable button
            ToolbarItem(id: "email", placement: .secondaryAction) {
                Button("Email Me") { }
            }

            // a third customizable button, but this one won't be in the toolbar by default
            ToolbarItem(id: "credits", placement: .secondaryAction, showsByDefault: false) {
                Button("Credits") { }
            }
        }
        .toolbarRole(.editor)
}

Download this as an Xcode project

When you run that code, you’ll see a details button on the trailing edge of your toolbar – tapping that will show a Customize Toolbar menu that enables customization.

By default this will make all the secondary action buttons individually customizable, but if you wrap two or more buttons in a ControlGroup they become attached for customization purposes – the user must add both or neither. ControlGroup is great for things like font adjustments, like this:

NavigationStack {
    Text("SwiftUI")
        .navigationTitle("Welcome")
        .toolbar(id: "font") {
            ToolbarItem(id: "font", placement: .secondaryAction) {
                ControlGroup {
                    Button {
                        // decrease font
                    } label: {
                        Label("Decrease font size", systemImage: "textformat.size.smaller")
                    }

                    Button {
                        // increase font
                    } label: {
                        Label("Increase font size", systemImage: "textformat.size.larger")
                    }
                } label: {
                    Label("Font Size", systemImage: "textformat.size")
                }
            }
        }
        .toolbarRole(.editor)
}

Download this as an Xcode project

Tip: If you don’t add a label for your ControlGroup, SwiftUI will use the labels for the buttons it contains.

Hacking with Swift is sponsored by Stream

SPONSORED Build a functional Twitter clone using APIs and SwiftUI with Stream's 7-part tutorial series. In just four days, learn how to create your own Twitter using Stream Chat, Algolia, 100ms, Mux, and RevenueCat.

Try now!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Similar solutions…

BUY OUR BOOKS
Buy Pro Swift Buy Pro SwiftUI Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

Average rating: 5.0/5

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.