TechnologiesSwiftUIControls and Style Configurations

ButtonRole struct

iOSmacOStvOSwatchOSvisionOSiOS 15.0+✓ renders

A value that describes the purpose of a button.

How it works

ButtonRole is a structure that describes the semantic purpose of a button, letting you tell SwiftUI what an action *means* rather than only how it looks. You attach a role when a button performs a meaningful action such as deleting data or canceling an operation, and SwiftUI uses that meaning to style the button appropriately and to emphasize it correctly in containers like menus, alerts, and confirmation dialogs. Reach for ButtonRole whenever an action carries weight that the system should communicate consistently across platforms, instead of hand-coding colors or font weights for each control.

  1. Pass a role to the Button initializer

    Buttons accept an optional role through an initializer parameter, so you declare semantics at the point of creation. In the example, Button("Delete", role: .destructive) and Button("Cancel", role: .cancel) carry roles, while Button("Save") omits the argument and stays a neutral action.

  2. Use the .destructive role for irreversible actions

    The destructive static member marks a button whose action removes data or cannot easily be undone. SwiftUI renders it with prominent, typically red styling so the consequence is obvious — that's why Button("Delete", role: .destructive) reads visually different from the plain Save button beside it.

  3. Use the .cancel role to dismiss without committing

    The cancel static member identifies the button that backs out of an operation. In dialogs and alerts SwiftUI gives it special placement and emphasis; here Button("Cancel", role: .cancel) declares that intent even within an ordinary VStack.

  4. Treat the role as optional semantics

    Because the role parameter is an Optional<ButtonRole>, a button without one — like Button("Save") — is simply unmarked and styled as a standard action. You only supply a role when the action has a meaning the system should recognize.

  5. Combine roles with a button style

    ButtonRole describes meaning; a style describes appearance, and the two compose. Applying .buttonStyle(.bordered) to the container lets each role tint and weight itself within that shared style, so .destructive and .cancel stay distinguishable while sharing the bordered look.

Try it — Wrap the three buttons in a .confirmationDialog or Menu instead of the VStack to see how .destructive and .cancel get system-driven emphasis and ordering that a plain stack doesn't apply.

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.

ButtonRole.swift
struct ButtonRoleDemo: View {
    var body: some View {
        VStack(spacing: 16) {
            Button("Delete", role: .destructive) {}
            Button("Cancel", role: .cancel) {}
            Button("Save") {}
        }
        .buttonStyle(.bordered)
        .padding()
    }
}
Live preview
Delete Cancel Save
Delete Cancel Save
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →