How to detect and respond to key press events
How to detect and respond to key press events 관련
Updated for Xcode 15
New in iOS 17
SwiftUI has an onKeyPress() modifier that lets us respond to hardware keyboard events being triggered in our app, with the only catch being that the view where you're watching for key presses must currently have input focus.
Watching for key presses takes various forms depending on what you want, but no matter what approach you take your view must be focusable in order to respond to a key press. So, this code marks a Text
view as being focusable and currently focused, then updates its contents whenever a key is pressed:
struct ContentView: View {
@FocusState private var focused: Bool
@State private var key = ""
var body: some View {
Text(key)
.focusable()
.focused($focused)
.onKeyPress { press in
key += press.characters
return .handled
}
.onAppear {
focused = true
}
}
}
The return .handled
part tells SwiftUI the key press has been responded to in full by our action closure. If you send back .ignored
instead, the key press will be passed on to whatever parent view is able to handle it next.
Note
The characters we receive do not have any modifier keys attached, so it won't give you things like uppercase letters or special symbols.
Other forms of onKeyPress()
include one to track which phase was triggered, so you could use this code to track only when a key has been released:
Text(key)
.onKeyPress(phases: .up) { press in
print("Received \(press.characters)")
return .handled
}
There's a variant that responds only to certain kinds of keys being pressed:
Text(key)
.onKeyPress(characters: .alphanumerics) { press in
print("Received \(press.characters)")
return .handled
}
And there's even a variant that responds to specific characters being pressed, provided either as a list of built-in constants or characters. So, this will listen for people frantically mashing keys to quit Vim:
Text(key)
.onKeyPress(keys: [.escape, "w", "q"]) { press in
print("Received \(press.characters)")
return .handled
}