How it works
A Button is a control that performs an action when the person interacting with your interface triggers it. You give it a label that describes the action and a closure that runs when it's activated, and SwiftUI takes care of the gesture handling, accessibility, and platform-appropriate appearance. Reach for Button whenever a tap, click, or press should make something happen — incrementing a value, submitting a form, navigating, or resetting state.
Create a button with a title and an action
The most concise initializer takes a title string and a trailing action closure, producing a button whose label is a
Textview. In the example,Button("Tap me") { count += 1 }shows the title and runs the closure each time it's activated, mutating the@Statevaluecount.Provide a custom label with the label: closure
When a plain string isn't enough, use the initializer that pairs an
actionclosure with alabelview builder, letting the label be any view. The example buildslabel: { Label("Reset", systemImage: "trash") }so the button presents text alongside an SF Symbol image instead of bare text.Signal intent with the role: parameter
A
ButtonRoletells SwiftUI the semantic purpose of the action so it can style the button and adjust accessibility accordingly. Passingrole: .destructivemarks the reset button as one that removes or undoes data, which the system can render with a cautionary appearance and announce appropriately.Shape the appearance with buttonStyle(_:)
The
buttonStyle(_:)modifier applies aButtonStyleto a button and to any buttons nested within that view hierarchy, separating how a button looks from what it does. Here.buttonStyle(.borderedProminent)gives the first button a filled, emphasized treatment; other built-in styles include.bordered,.borderless, and.plain.
.buttonStyle(.borderedProminent) to .buttonStyle(.bordered) to see how the same Button adopts a lighter, less emphasized appearance without touching its action.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.
struct ButtonDemo: View {
@State private var count = 0
var body: some View {
VStack(spacing: 16) {
Text("Taps: \(count)")
.font(.headline)
Button("Tap me") {
count += 1
}
.buttonStyle(.borderedProminent)
Button(role: .destructive) {
count = 0
} label: {
Label("Reset", systemImage: "trash")
}
}
.padding()
}
}