Toolbars usually fail at the edges of a layout, not at the ideal size in a design file. A Mac window narrows, an iPad enters a split view, or an iPhone view gains a more compact presentation. If every action has equal importance, SwiftUI has no useful signal for deciding what should stay visible.
The newer toolbar APIs make that signal explicit. They are most useful when the toolbar starts from an action hierarchy, rather than from a list of buttons that happen to fit today.
Classify actions before assigning placements
Start by separating actions into three groups:
- frequent actions that should remain visible;
- useful actions that can move into an overflow menu;
- destructive or contextual actions that belong near the content that owns them.
This makes visibilityPriority(_:) a product decision instead of a cosmetic tweak. Give the actions needed to continue the current task a high priority, then use ToolbarOverflowMenu for commands that should remain available without permanently consuming width.
struct EditorView: View {
var body: some View {
DocumentCanvas()
.toolbar {
ToolbarItemGroup {
UndoButton()
RedoButton()
}
.visibilityPriority(.high)
ToolbarOverflowMenu {
Button("Export", action: exportDocument)
Button("Duplicate", action: duplicateDocument)
}
}
}
}The overflow menu should not be a dumping ground. Keep related, lower-frequency operations together, and leave the one action that represents the current flow in the visible toolbar. If a command needs immediate attention, it is usually a poor candidate for overflow.
The same hierarchy applies to tabs. A Tab(role: .prominent) is appropriate for the one destination that represents the primary action, such as a cart or compose flow. Use it sparingly. If every tab is promoted, the tab bar has no priority left to communicate.
Let long content create more room
Some toolbars become large because they stay visible while the person is reading or scrolling. For navigation content where the bar is not required continuously, toolbarMinimizeBehavior(_:for:) can reduce its presence on a downward scroll.
ScrollView {
ArticleBody()
}
.toolbarMinimizeBehavior(.onScrollDown, for: .navigationBar)Minimization is not appropriate for every screen. An editor with an always-needed formatting control or an accessibility-critical action may need a stable bar. Use it where the screen benefits from more content space, then verify that the toolbar returns at a predictable moment and does not hide the only route to a key action.
Design for resize, not device idioms
SwiftUI interfaces already adapt across platforms, but the iPhone can now also appear in more resizable contexts. A layout that relies on one fixed "phone" width is more likely to expose crowded toolbars, clipped titles, and controls that are hard to reach.
Test a range of widths in Xcode previews and during actual interaction. Prefer size classes and the available geometry over selecting a layout solely from the device idiom. For mixed UIKit and SwiftUI applications, this is especially important because older geometry assumptions can conflict with a resizable SwiftUI scene.
The same review should include menu content. Current iPad and Mac menu bars use fewer icons by default, reserving them for the actions that need visual emphasis. If a command genuinely needs an icon in its label, opt into .labelStyle(.titleAndIcon) deliberately instead of making every menu entry compete for attention.
Make active state part of the hierarchy
On iPad and Mac, inactive windows receive a dimmed appearance automatically. Custom controls can match that system cue with the appearsActive environment value. This is a small addition, but it avoids the common mismatch where system chrome looks inactive while a custom sidebar control still looks selected and actionable.
struct AccountControl: View {
@Environment(\.appearsActive) private var appearsActive
var body: some View {
Button("Account", action: showAccount)
.opacity(appearsActive ? 1 : 0.5)
}
}The goal is not to recreate every system effect. It is to ensure custom controls participate in the same visual hierarchy as the surrounding interface.
Toolbars become more resilient when they have a clear order of importance. Encode that order with visibility priority and overflow menus, minimize chrome only when content needs the space, then test the result across real widths. The APIs are new and marked beta in current documentation, so verify their final availability before shipping.
