TechnologiesSwiftUI

CommandGroup struct

iOSmacOStvOSwatchOSvisionOS✓ renders

Groups of controls that you can add to existing command menus.

How it works

CommandGroup describes a related set of menu commands that you contribute to your app's main menu on macOS. SwiftUI organizes the standard menu bar into predefined groups — New, Open, Save, Undo, Cut/Copy/Paste, and so on — and CommandGroup lets you add your own buttons alongside those groups, replace a system group entirely, or insert items before or after one. You build commands as part of a Scene's commands modifier rather than inside a view hierarchy, so reach for CommandGroup whenever you need to extend or customize what appears in the menu bar.

  1. Add commands in a Scene's commands modifier

    Menu commands live at the scene level, not inside body, so you attach them with the .commands modifier on a WindowGroup or other Scene. The closure is a command builder, and each CommandGroup you return contributes a block of menu items — as shown by the .commands { CommandGroup(...) } form in the example.

  2. Target a system group with a CommandGroupPlacement

    Every CommandGroup initializer takes a CommandGroupPlacement that names the standard menu group to act on, such as .newItem, .saveItem, or .appInfo. The example passes .newItem, which addresses the New / Open area of the File menu so your commands land in a place users already expect.

  3. Replace, or insert before/after, the existing group

    Three initializers control how your items combine with the system's: CommandGroup(replacing:) swaps out the built-in commands for your own, while CommandGroup(before:) and CommandGroup(after:) keep them and add your items adjacent. The example uses CommandGroup(replacing: .newItem) to take over the New entry completely.

  4. Supply the menu items in the content closure

    The trailing closure is where you declare the actual menu entries, typically as Buttons whose action runs your command and whose title becomes the menu label. The example provides Button("New") {}, which renders as a single "New" item in the File menu; add keyboard shortcuts with .keyboardShortcut on those buttons.

Try it — Change CommandGroup(replacing: .newItem) to CommandGroup(after: .newItem) and watch your "New" button appear alongside the system command instead of taking its place.

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.

CommandGroup.swift
struct CommandGroupDemo: View {
    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("App Commands")
                .font(.headline)
            Text("CommandGroup adds items to the macOS menu bar inside a Scene's .commands modifier:")
                .font(.caption)
                .foregroundStyle(.secondary)
            VStack(alignment: .leading, spacing: 6) {
                Label("New", systemImage: "doc.badge.plus")
                Label("Open\u{2026}", systemImage: "folder")
                Divider()
                Label("Export\u{2026}", systemImage: "square.and.arrow.up")
            }
            .padding(10)
            .background(.regularMaterial, in: RoundedRectangle(cornerRadius: 8))
            Text(".commands { CommandGroup(replacing: .newItem) { Button(\"New\") {} } }")
                .font(.system(.caption2, design: .monospaced))
                .foregroundStyle(.blue)
        }
        .padding()
    }
}
Live preview
App Commands CommandGroup adds items to the macOS menu bar inside a Scene's .commands modifier: New Open\u{2026} Export\u{2026} .commands { CommandGroup(replacing: .newItem) { Button(\"New\") {} } }
App Commands CommandGroup adds items to the macOS menu bar inside a Scene's .commands modifier: New Open\u{2026} Export\u{2026} .commands { CommandGroup(replacing: .newItem) { Button(\"New\") {} } }
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →