How it works
ToolbarContentBuilder is a result builder that lets you declare the contents of a toolbar as a sequence of toolbar items, the same way ViewBuilder lets you declare a view hierarchy. Whenever you pass a closure to a toolbar modifier or write a type that conforms to ToolbarContent, the compiler applies this builder behind the scenes, collecting each item you list into a single composed result. Reach for it when you need to express toolbar layout declaratively — listing several items, grouping them, and placing them — without manually assembling an array. In practice you rarely name it directly; you benefit from it every time you populate a toolbar.
Open a builder closure with the toolbar(content:) modifier
Attaching
.toolbar { ... }to a view hands you a trailing closure that is annotated with @ToolbarContentBuilder. Inside that closure you simply list toolbar items top to bottom, and the builder gathers them into the ToolbarContent the modifier expects. Here the closure is attached toText("Inbox")within aNavigationStack, which is where the resulting items are hosted.List items with ToolbarItem
Each
ToolbarItemyou write becomes one element the builder collects, wrapping an arbitrary view such as a control. Because the closure is a builder, you can place several items one after another with no separators or commas — the example lists twoToolbarItementries back to back, one holdingButton("Edit")and another holding aButtonwhose label isImage(systemName: "square.and.pencil").Bundle related controls with ToolbarItemGroup
ToolbarItemGroupis itself valid toolbar content, so the builder accepts it alongside individual items and treats its children as a related cluster sharing one placement. The example uses a singleToolbarItemGroupto gather a trashButton, aSpacer, and aText("3 messages")into one bottom-bar group.Steer each item with placement
Every item the builder collects carries a
placementargument that tells SwiftUI where in the toolbar to position it. The builder preserves these placements while composing, so the example can route items to.topBarLeading,.topBarTrailing, and.bottomBarindependently even though they are all declared in the same closure.Compose ToolbarContent without an array
Under the hood ToolbarContentBuilder turns the listed items into a single value conforming to ToolbarContent, the toolbar analogue of a built View. This is what frees you from constructing or returning an explicit collection: you declare the items, and the builder produces the composed content that the
.toolbarmodifier installs.
ToolbarItem(placement: .topBarLeading) holding Button("Edit") to .topBarTrailing and watch the builder re-place that same item beside the compose button without changing anything else.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 ToolbarContentBuilderDemo: View {
var body: some View {
NavigationStack {
Text("Inbox")
.padding()
.navigationTitle("Mail")
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button("Edit") {}
}
ToolbarItem(placement: .topBarTrailing) {
Button {
} label: {
Image(systemName: "square.and.pencil")
}
}
ToolbarItemGroup(placement: .bottomBar) {
Button {
} label: {
Image(systemName: "trash")
}
Spacer()
Text("3 messages")
}
}
}
}
}