Controlling keyboard events with keys and phases
Learn how to respond to pressed keys and phases in a hardware keyboard in a SwiftUI app.
The onKeyPress(_:action:)
method is present in several variations, providing complete control over triggering actions. These variations allow the developer to specify exactly how and when actions should be executed in response to key presses.
The behavior can be customized by specifying:
- particular keys being pressed;
- the phase of a key press;
- a combination of both keys and their phases;
- the characters produced by the pressed keys.
onKeyPress
modifier works with physical keyboards.Specifying the key pressed with onKeyPress(_:action:)
It triggers a specific action when a particular key is pressed on a hardware keyboard, provided the view is in focus.
MyView()
.onKeyPress(
// 1. The key that triggers the action once it is pressed
KeyEquivalent("a"),
// 2. The action to perform
action: {
print("You have just pressed the 'a' key ")
// 3. Returning value
return .handled
}
)
The method needs two parameters:
- A key, a
KeyEquivalent
type, consisting of any letter, punctuation, or function key being pressed on the hardware keyboard; - The action that will be performed once one or more keys have been pressed.
The following is an example of the modifier being implemented on a view:
import SwiftUI
struct ContentView: View {
@FocusState var isFocused: Bool?
@State var text: String = "Hello, world!"
@State var input: String = ""
var body: some View {
VStack {
Image(systemName: "keyboard")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Press the 'a' key to change the text below")
.foregroundStyle(.secondary)
Text(text)
.foregroundStyle(.secondary)
Divider()
TextField("Press the keys", text: $input)
.frame(width: 200)
.padding(.horizontal)
.focusable()
.focused($isFocused, equals: true)
// The method
.onKeyPress(KeyEquivalent("a"), action: {
text = "You have just pressed the 'a' key"
return .handled
})
}
.padding()
.onAppear(perform: {
isFocused = true
})
}
}
Specifying the phase with onKeyPress(phases:action:)
It triggers a specific action when any key is pressed on a hardware keyboard, based on the phase
of the KeyPress
, provided the view is in focus.
.onKeyPress(
// 1. The phase that triggers the action
phases: .up,
// 2. The action to perform
action: {
// 3. The key being pressed
pressedKey in
text = "You have just pressed and released the '\(pressedKey.key.character)' key"
// 4. Returning value
return .handled
}
)
This method works as follows:
- It takes a
phases
parameter, aKeyPress.Phases
collection type that describes the different phases of a key-press event, which can be set. By default, the value is set to[.down, .repeat]
. - It takes the action to be performed once one or more keys have been pressed.
- The information regarding the pressed key is provided to the action as a
KeyEquivalent
object. - The returning value to handle the action.
Specifying one key and the phase with onKeyPress(_:phases:action:)
It triggers an action when a specific key is pressed on a hardware keyboard, based on a specificphase
of the KeyPress
, provided the view is in focus.
// The method
.onKeyPress(
// 1. The key to be pressed
KeyEquivalent("a"),
// 2. The phase that triggers the action
phases: [.down, .up],
// 3. The action to perform
action: { pressedKey in
if pressedKey.phase == .down {
text = "You are pressing the '\(pressedKey.key.character)' key"
} else if pressedKey.phase == .up {
text = "You have just released the '\(pressedKey.key.character)' key"
}
// 4. Returning value
return .handled
}
)
This method takes 3 parameters:
- The key to be pressed to trigger the action;
- The phases when triggering the action - that can be of value
down
,repeat
, andup
; - The
action
to be performed.
Specifying a set of keys and the phase with onKeyPress(keys:phases:action:)
It triggers an action when specific keys are pressed on a hardware keyboard, based on a specific phase
of the KeyPress
, provided the view is in focus.
// The method
.onKeyPress(
// 1. The key to be pressed
keys: [KeyEquivalent("o"), KeyEquivalent("k")],
// 2. The phase that triggers the action
phases: .up,
// 3. The action to perform
action: { _ in
text = "You've just pressed and released the \(pressedKey.key.character) keys"
// 4. Returning value
return .handled
}
)
This method takes 3 parameters:
- The keys, a collection of the
KeyEquivalent
type to be pressed to trigger the action; - The phases when triggering the action - that can be of value
down
,repeat
, andup
, set as[.down, .repeat]
by default. - The action to be performed.
Specifying characters with onKeyPress(characters:phases:action:)
It triggers an action when specific characters are generated by keys being pressed on a hardware keyboard, at a givenphase
of the KeyPress
, provided the view is in focus.
// The method
.onKeyPress(
// 1. The characters to be generated
characters: .letters,
// 2. The phase that triggers the action
phases: .up,
// 3. The action to perform
action: { _ in
text = "You've just pressed and released the \(pressedKey.key.character) key"
// 4. Returning value
return .handled
}
)
This method takes 3 parameters:
- The characters, of type
CharacterSet
, representing the set of characters generated by the pressed key; - The phases when triggering the action - that can be of value
down
,repeat
, andup
, set as[.down, .repeat]
by default.; - The action to be performed.