How to let users customize toolbar buttons
How to let users customize toolbar buttons 관련
Updated for Xcode 15
SwiftUI's toolbar allows the user to customize any toolbar items we allow, and it takes five small steps:
- Give your toolbar a unique, stable identifier string.
- Give each customizable toolbar item a unique, stable identifier string.
- Place customizable buttons in the
.secondaryAction
category. - Decide which buttons should be visible by default.
- 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)
}
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)
}
Tips
If you don't add a label for your ControlGroup
, SwiftUI will use the labels for the buttons it contains.