TechnologiesSwiftUI

ControlGroupStyle protocol

iOSmacOStvOSwatchOSvisionOS✓ renders

Defines the implementation of all control groups within a view

How it works

ControlGroupStyle is the protocol that defines how a ControlGroup lays out and presents its collection of controls. SwiftUI groups related controls — typically buttons — into a single coherent unit, and the style determines whether that unit appears as a horizontal cluster, a navigation-bar arrangement, a compact menu, or a platform default. Conform a type to ControlGroupStyle, or pick one of the built-in styles, when you want a set of related actions to read as one component rather than as loose, independently-styled buttons. Reach for it whenever a control group's default appearance doesn't match the context where it sits.

  1. Apply a style with controlGroupStyle(_:)

    You don't usually conform to ControlGroupStyle directly to use it — you select a style and attach it with the controlGroupStyle(_:) modifier. The modifier accepts any conforming style and propagates it to the ControlGroup (and to control groups nested below it) through the environment. Here it is written as .controlGroupStyle(.navigation) on the group's view.

  2. Choose a built-in style value

    SwiftUI ships several conforming styles exposed as static members, so you pass a value like .navigation, .automatic, .compactMenu, or .menu rather than constructing a type. Each one tells the group how to arrange its members: .navigation lays the controls out the way a navigation bar would, while .automatic defers to the platform default. The example selects .navigation.

  3. Let the group own its members

    The style operates on whatever controls the ControlGroup's content closure supplies — it restyles the group as a whole instead of each control individually. In the example the closure holds three Button views, each with a Label (Add/plus, Remove/minus, Edit/pencil); the chosen ControlGroupStyle decides how those three are clustered and spaced relative to one another.

  4. Conform a custom type when the built-ins fall short

    To define your own arrangement, declare a type conforming to ControlGroupStyle and implement makeBody(configuration:), returning a view built from the supplied Configuration (which vends a content view representing the group's controls). You then pass an instance of that type to controlGroupStyle(_:) exactly as you'd pass .navigation, giving the group bespoke layout while keeping the same call site.

Try it — Change .controlGroupStyle(.navigation) to .controlGroupStyle(.compactMenu) and watch the three buttons collapse from an inline cluster into a single menu control.

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.

ControlGroupStyle.swift
struct ControlGroupStyleDemo: View {
    var body: some View {
        ControlGroup {
            Button {
            } label: {
                Label("Add", systemImage: "plus")
            }
            Button {
            } label: {
                Label("Remove", systemImage: "minus")
            }
            Button {
            } label: {
                Label("Edit", systemImage: "pencil")
            }
        }
        .controlGroupStyle(.navigation)
        .padding()
    }
}
Live preview
Add Remove Edit
Add Remove Edit
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →