How it works
KeyPress is the value SwiftUI hands you each time a focused view receives keyboard input, packaging the pressed key together with its modifiers and the phase of the event. Reach for it when you want a view to respond to hardware keyboard activity directly — arrow-key navigation, shortcut letters, Return to confirm — rather than relying on a text field or a menu command. Because it arrives as a structured value, you inspect its properties to decide whether a given key concerns you, and report back whether you consumed the event.
Make the view eligible for key input with focusable()
Key presses are only delivered to a view that can hold keyboard focus, so the view must opt in before any KeyPress arrives. Here
.focusable()marks the input surface, establishing the focus target that the keyboard events flow to.Receive each event in the onKeyPress closure
The
onKeyPressmodifier installs a handler whose closure is called with a single KeyPress value for every qualifying key event. In the example the parameter is named and typed explicitly,(press: KeyPress), giving you a fresh value to examine on each keystroke.Read the pressed key through the key property
KeyPress exposes the physical key via its
keyproperty, a KeyEquivalent that carries the actual character produced. The example readspress.key.characterto build its display string, which is how arrow keys, Return, and letters all surface through the same value.Report the outcome with KeyPress.Result
The closure must return a KeyPress.Result so SwiftUI knows whether the event was consumed or should keep propagating. Returning
.handledtells the system you dealt with this press; returning.ignoredwould let it pass on to other responders.
.handled to .ignored and observe that, while lastKey still updates, the key press now also flows on to the rest of the responder chain instead of being consumed here.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 KeyPressDemo: View {
@State private var lastKey = "Press any key"
var body: some View {
VStack(spacing: 12) {
Text("Keyboard Input")
.font(.headline)
Text(lastKey)
.font(.title2.monospaced())
.foregroundStyle(.tint)
Text("Try arrow keys, return, or letters")
.font(.caption)
.foregroundStyle(.secondary)
}
.padding()
.focusable()
.onKeyPress { (press: KeyPress) in
lastKey = "Key: \(press.key.character)"
return .handled
}
}
}