How it works
ToolbarOverflowMenu collects a set of toolbar controls into a single, system-managed overflow menu, presented from a compact "more" affordance. Reach for it when a toolbar offers more actions than the available space can comfortably display, or when several related but secondary commands belong together rather than competing for prominence alongside primary controls. Rather than hand-placing every button, you declare the actions inside the menu and let SwiftUI surface them on demand, keeping the bar uncluttered while leaving every command reachable.
Place ToolbarOverflowMenu inside the toolbar
ToolbarOverflowMenuis a toolbar content type, so it lives inside thetoolbarmodifier rather than in the main view hierarchy. Here it is attached to theText("Edit your document")view of aNavigationStack, which gives the menu a bar to render into and anavigationTitle("Notes")to sit alongside.Position it with ToolbarItemGroup and a placement
Wrapping the menu in
ToolbarItemGroup(placement: .primaryAction)tells SwiftUI where on the bar the overflow affordance should appear. The.primaryActionplacement puts it in the leading edge of the trailing action area on most platforms, so the collapsed menu reads as the screen's main set of commands.Declare the actions in the trailing closure
ToolbarOverflowMenutakes a content closure whose views become the menu's entries. The fourButtonitems —"Share","Duplicate","Rename", and"Delete"— are listed in order, and SwiftUI lays them out as a vertical menu when the affordance is tapped, so you describe the commands without managing presentation.Give each entry a label and system image
Each
Buttonpairs a title with asystemImage, such as"square.and.arrow.up"for Share and"trash"for Delete, so the overflow menu renders consistent SF Symbol rows. The menu adopts the same labeling that buttons use elsewhere in the toolbar, keeping the iconography uniform whether an action is shown directly or tucked into the overflow.Signal intent with a button role
Because menu entries are ordinary buttons, semantic roles flow through unchanged. Marking the last
Buttonwithrole: .destructiveletsToolbarOverflowMenustyle the Delete row distinctly — typically tinted red and grouped at the end — so a dangerous command stands apart from the routine ones.
Button("Export", systemImage: "arrow.up.doc") {} inside the ToolbarOverflowMenu closure and watch SwiftUI fold the new command into the same overflow menu without changing the bar's footprint.Example & preview
Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.
struct ToolbarOverflowMenuDemo: View {
var body: some View {
NavigationStack {
Text("Edit your document")
.padding()
.navigationTitle("Notes")
.toolbar {
ToolbarItemGroup(placement: .primaryAction) {
ToolbarOverflowMenu {
Button("Share", systemImage: "square.and.arrow.up") {}
Button("Duplicate", systemImage: "plus.square.on.square") {}
Button("Rename", systemImage: "pencil") {}
Button("Delete", systemImage: "trash", role: .destructive) {}
}
}
}
}
}
}