SwiftUI.cc
Snippets
StylingCustom StylingAdvanced

SwiftUI Custom ButtonStyle, ToggleStyle, and LabelStyle

Create reusable control styles when repeated UI behavior belongs to the component system rather than a single screen.

6 min readUpdated 2026-06
Primary button style
import SwiftUI

struct PrimaryActionStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .font(.headline)
            .frame(maxWidth: .infinity)
            .padding(.vertical, 12)
            .background(.teal, in: RoundedRectangle(cornerRadius: 12))
            .foregroundStyle(.white)
            .opacity(configuration.isPressed ? 0.72 : 1)
            .scaleEffect(configuration.isPressed ? 0.98 : 1)
    }
}

extension ButtonStyle where Self == PrimaryActionStyle {
    static var primaryAction: PrimaryActionStyle { PrimaryActionStyle() }
}
Use this when

Many buttons, toggles, labels, or progress views should share interaction and visual treatment.

Pressed, enabled, or selected states need consistent behavior across screens.

The style is a design-system primitive instead of local decoration.

Avoid this when

A one-off view modifier is enough for a single screen.

The style hides business logic or navigation.

The custom control stops behaving like the platform control users expect.

Implementation notes

Style configuration gives access to label content and state without requiring every caller to duplicate modifiers.
Apply a style at a container level only when every child control should inherit it.
Keep styles visual and interactive; do not hide persistence or networking inside them.

Checklist

Test disabled, pressed, loading, and accessibility states.

Keep hit targets at comfortable sizes.

Make icon-only labels accessible.

Related reference