BLACK FRIDAY: Save 50% on all my Swift books and bundles! >>

Placing toolbar buttons in exact locations

Paul Hudson    @twostraws   

If you place buttons in a NavigationStack toolbar, SwiftUI will place them automatically based on the platform your code is running on. We're building iOS apps here, so that means our buttons will be placed in the right-hand side of the navigation bar in languages that are read left-to-right, such as English.

You can customize this if you want, using ToolbarItem. This goes around your toolbar buttons, allowing you to place them exactly where you want by choosing from one of several options.

For example, we can ask for a left-hand placement like this:

NavigationStack {
    Text("Hello, world!")
    .toolbar {
        ToolbarItem(placement: .topBarLeading) {
            Button("Tap Me") {
                // button action here
            }
        }
    }
}

Although that works well, usually it's better to use one of the semantic options – placement that have specific meaning, rather than relying just on their location. These include:

  • .confirmationAction, when you want users to agree to something, such as agreeing to terms of service.
  • .destructiveAction, when the user needs to make a choice to destroy whatever it is they are working with, such as confirming they want to remove some data they created.
  • .cancellationAction, when the user needs to back out of changes they have made, such as discarding changes they have made.
  • .navigation, which is used for buttons that make the user move between data, such as going back and forward in a web browser.

These semantic placements come with two important benefits. First, because iOS has extra information about what your buttons do, it can add extra styling – a confirmation button can be rendered in bold, for example. Second, these positions automatically adapt on other platforms, so your button will always appear in the correct place on iOS, macOS, watchOS, and more.

Tip: If you need the user to decide between saving a change or discarding it, you might want to add the navigationBarBackButtonHidden() modifier so that they can't tap Back to exit without making a choice.

If you want multiple buttons using the same placement, you can either repeat ToolbarItem like this:

.toolbar {
    ToolbarItem(placement: .topBarLeading) {
        Button("Tap Me") {
            // button action here
        }
    }

    ToolbarItem(placement: .topBarLeading) {
        Button("Or Tap Me") {
            // button action here
        }
    }
}

Or you can use ToolbarItemGroup, like this:

.toolbar {
    ToolbarItemGroup(placement: .topBarLeading) {
        Button("Tap Me") {
            // button action here
        }

        Button("Tap Me 2") {
            // button action here
        }
    }
}

Both should produce the same result.

Save 50% in my WWDC sale.

SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

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: 4.8/5

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.