TechnologiesSwiftUIControls and Style Configurations

PrimitiveButtonStyleConfiguration struct

iOSmacOStvOSwatchOSvisionOSiOS 13.0+✓ renders

The properties of a button.

How it works

PrimitiveButtonStyleConfiguration carries the properties of a button into a custom PrimitiveButtonStyle, giving you everything you need to build the button's appearance from scratch. Unlike ButtonStyle, a primitive style is responsible for the button's interaction as well as its look, so the configuration hands you both the button's label and a trigger() action to fire when you decide the button has been activated. Reach for it when a standard tap isn't enough and you need full control over how a button presents itself and what counts as a press.

  1. Receive the configuration in makeBody(configuration:)

    A type conforming to PrimitiveButtonStyle implements makeBody(configuration:), where the parameter is a PrimitiveButtonStyleConfiguration (aliased as Configuration). SwiftUI calls this method for every button using the style and passes in the live configuration, as CapsuleButtonStyle does with its makeBody(configuration:) returning some View.

  2. Compose the button's content with the label property

    The label property is a type-erased view holding the content you passed when creating the button. You treat it as the body of your design and decorate it freely; here configuration.label is styled with .font(.headline), .foregroundStyle(.white), padding, and a .background(.blue, in: Capsule()) to produce the capsule appearance.

  3. Activate the button by calling trigger()

    Because a primitive style owns interaction, the configuration exposes a trigger() method that performs the button's action. You invoke it from whatever gesture or event you choose to treat as a press, which is why the example wires .onTapGesture { configuration.trigger() } to run the button's closure on tap.

  4. Install the style with buttonStyle(_:)

    Applying your PrimitiveButtonStyle to a Button (or a view hierarchy of buttons) is done through the buttonStyle(_:) modifier, which is what connects the configuration to a real control. In the example .buttonStyle(CapsuleButtonStyle()) is what causes SwiftUI to build a PrimitiveButtonStyleConfiguration for the "Get Started" button and route it through makeBody.

Try it — Replace .onTapGesture { configuration.trigger() } with a .onLongPressGesture { configuration.trigger() } so the same configuration only activates the button after a press-and-hold, showing that trigger() defines when activation happens.

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.

PrimitiveButtonStyleConfiguration.swift
struct PrimitiveButtonStyleConfigurationDemo: View {
    struct CapsuleButtonStyle: PrimitiveButtonStyle {
        func makeBody(configuration: Configuration) -> some View {
            configuration.label
                .font(.headline)
                .foregroundStyle(.white)
                .padding(.horizontal, 24)
                .padding(.vertical, 12)
                .background(.blue, in: Capsule())
                .onTapGesture { configuration.trigger() }
        }
    }

    var body: some View {
        Button("Get Started") { }
            .buttonStyle(CapsuleButtonStyle())
            .padding()
    }
}
Live preview
Get Started
Get Started
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →