SwiftUI.cc
Snippets
ControlsMenusIntermediate

SwiftUI ControlGroup Styles in Toolbars

ControlGroup visually unifies related controls — undo/redo, zoom in/out — adapting per context, with compactMenu and palette styles condensing groups in menus and toolbars.

3 min readUpdated 2026-06
Editor toolbar with grouped history controls
import SwiftUI

struct EditorBar: View {
    var body: some View {
        NavigationStack {
            Text("Canvas")
                .toolbar {
                    ToolbarItem(placement: .topBarTrailing) {
                        ControlGroup {
                            Button("Undo", systemImage: "arrow.uturn.backward") { }
                            Button("Redo", systemImage: "arrow.uturn.forward") { }
                        }
                    }
                    ToolbarItem(placement: .topBarTrailing) {
                        Menu("Edit") {
                            ControlGroup {
                                Button("Cut", systemImage: "scissors") { }
                                Button("Copy", systemImage: "doc.on.doc") { }
                                Button("Paste", systemImage: "doc.on.clipboard") { }
                            }
                            .controlGroupStyle(.palette)
                        }
                    }
                }
        }
    }
}

ControlGroup preview

Semantic grouping

ControlGroup { undoButton; redoButton } tells the system these controls form one logical unit. The framework then renders the platform-correct cluster: a joined bordered capsule in an iOS toolbar, a segmented-looking cluster on Mac, a horizontal strip inside a menu. You declare the relationship; rendering is contextual.

Styles

ControlGroup {  }.controlGroupStyle(.palette)      // icon strip (menus)
ControlGroup {  }.controlGroupStyle(.compactMenu)  // collapses to one element

.palette is the cut/copy/paste row at the top of edit menus. .compactMenu shrinks a labeled group into a single button that pops its members — useful when toolbar real estate is scarce but the actions deserve grouping.

In context menus and toolbars

ControlGroup composes inside Menu, contextMenu, and toolbar items alike. The grouping survives overflow: when a toolbar collapses items into the system overflow menu, grouped controls stay together — a robustness win over visually faking groups with spacing.

Common mistakes

  • Grouping by appearance ("these are all icons") instead of function.
  • Forgetting the group label, so compactMenu collapses into an unnamed mystery button.
  • Re-implementing the cluster look with HStack + background and losing adaptive behavior.

Related reference