Snippets
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
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() }
}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
Reusable SwiftUI ViewModifier and Shape Styling
Move repeated visual decisions into ViewModifier and Shape extensions so the UI reads like product language.
SwiftUI foregroundStyle and tint
Prefer foregroundStyle and tint for modern SwiftUI color styling, especially when controls, symbols, gradients, and semantic materials mix.
SwiftUI disabled, redacted, and allowsHitTesting
Represent unavailable, loading, private, and pass-through states with the right interaction and visual modifiers.