TechnologiesSwiftUI

ButtonStyle protocol

iOSmacOStvOSwatchOSvisionOSiOS 13.0+✓ renders

A type that applies standard interaction behavior and a custom appearance to

How it works

ButtonStyle is a protocol that lets you define a reusable appearance and interaction behavior for buttons, then apply it consistently throughout your app. Instead of attaching the same chain of modifiers to every Button, you describe the styling once in a type that conforms to ButtonStyle and hand it to the buttonStyle(_:) modifier. SwiftUI calls into your style to build each button's body, passing along the button's label and its current pressed state. Reach for ButtonStyle whenever you want a custom button look that responds to user interaction and stays consistent across many call sites.

  1. Conform a type to ButtonStyle

    A button style is any type that adopts the ButtonStyle protocol; typically a small struct so it stays lightweight and value-based. Here GradientButtonStyle declares conformance with struct GradientButtonStyle: ButtonStyle, giving you a named, reusable style you can apply to any button.

  2. Implement makeBody(configuration:)

    The single required method, makeBody(configuration:), returns the view that represents the styled button. SwiftUI invokes it to render the button, and you return some View describing the final appearance — in this case the label wrapped in padding, a gradient background, and a capsule shape.

  3. Compose around configuration.label

    The configuration parameter (of the associated Configuration type) carries configuration.label, a type-erased view representing the button's title or content. You build your style by decorating it: the example takes configuration.label and chains .padding, .background with a LinearGradient, .foregroundStyle(.white), and .clipShape(Capsule()).

  4. React to configuration.isPressed

    configuration.isPressed reports whether the user is currently pressing the button, letting your style provide interactive feedback. The example reads it to shrink the button while held with .scaleEffect(configuration.isPressed ? 0.95 : 1), so the press state visibly drives the appearance.

  5. Apply the style with buttonStyle(_:)

    You attach a custom style by passing an instance to the buttonStyle(_:) modifier, which also propagates down to descendant buttons in the view hierarchy. The example wires up its style with .buttonStyle(GradientButtonStyle()) on the Button("Get Started"), replacing the system look with the gradient capsule.

Try it — Change 0.95 in .scaleEffect(configuration.isPressed ? 0.95 : 1) to 1.1 so the button grows instead of shrinking on press, revealing how configuration.isPressed drives the style's interactive feedback.

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.

ButtonStyle.swift
struct ButtonStyleDemo: View {
    struct GradientButtonStyle: ButtonStyle {
        func makeBody(configuration: Configuration) -> some View {
            configuration.label
                .padding(.horizontal, 24)
                .padding(.vertical, 12)
                .background(
                    LinearGradient(
                        colors: [.purple, .blue],
                        startPoint: .leading,
                        endPoint: .trailing
                    )
                )
                .foregroundStyle(.white)
                .clipShape(Capsule())
                .scaleEffect(configuration.isPressed ? 0.95 : 1)
        }
    }

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