How to capture the currently pressed key when a TextField is in focus?

In the attached code snippet:

struct ContentView: View {
@State private var vText: String = ""
var body: some View {
TextField("Enter text", text: Binding(
get: { vText },
set: { newValue in
print("Text will change to: \(newValue)")
vText = newValue
}
))
}
}

I have access to the newValue of the text-field whenever the text-field content changes, but how do I detect which key was pressed? I can manually get the diff between previous state and the new value to get the last pressed char but is there a simpler way? Also this approach won't let me detect any modifier keys (such as Alt, Ctrl etc) that the user may have pressed.

Is there a pure swift-ui approach to detect these key presses?

Did you try to use .onChange ? If you want to detect a pressed key (but not a typed character in the TextField, that will not do it.

or onKeyPress ?

More details here: https://www.avanderlee.com/swiftui/key-press-events-detection/#:~:text=Key%20press%20events%20detection%20in%20SwiftUI%20allows%20you%20to%20listen,able%20to%20get%20any%20callbacks.

Something like:

struct ContentView: View {
@State private var vText: String = ""
var body: some View {
HStack {
TextField("Enter text", text: Binding(
get: { vText },
set: { newValue in
// print("Text will change to: \(newValue)")
vText = newValue
}
))
.onChange(of: vText) { oldText, newText in
let typed = newText.replacingOccurrences(of: oldText, with: "")
if newText.count < oldText.count {
print("backspace")
} else {
print("typed char is: ", typed)
}
}
}
.onKeyPress(characters: .alphanumerics, /*phases: .up, */action: { keyPress in
print("Released key \(keyPress.characters)")
return .ignored // handled would intercept the typing
})
}
}

@raunits Could you elaborate on what you’re trying to acheive and why observing the presses on the hardware keyboard is important? Depending on what your end goal is we could point you to the right direction. But as Claude mentioned, onKeyPress is a good starting point if you want to perform an action when a user presses a key on the keyboard.

Thanks for the quick responses!

@Claude31 's solution covers almost all my use cases except for one. I am unable to detect modifier-only keypresses with the above approach.

TextField ("Enter text...", text: $txt)
.onKeyPress(action: {keyPress in
print ("key: \(keyPress.key), modifier: \(keyPress.modifiers)");
return .ignored;
})

For eg, nothing gets printed when I press only the Alt key. I ask this since my application has to allow the user to experience additional functionality on press of special keys - like pressing the Alt key may trigger a particular menu on a particular screen. How can I detect such keypresses, or is it not possible by design?

The intent is to be able to implement custom functionality corresponding to an extensive set of hotkey combinations and modifier-only keys. Please correct me if I'm approaching the problem in the wrong direction.

How to capture the currently pressed key when a TextField is in focus?
 
 
Q