UITextView's pressesBegan isn't triggered by the software keyboard

I'm building a SwiftUI app with a UITextView subclass, and it seems that the software keyboard doesn't trigger the pressesBegan or pressesEnded functions of UITextView. With a hardware keyboard, pressesBegan works as expected, allowing us to intercept key presses in our subclass.

I can't find any documentation about this, or any other forum posts (here or on Stack Overflow) that talk about a discrepancy between software and hardware keyboard behaviors, and I can't believe this is an intended behavior. Our app is a SwiftUI app, in case that's relevant.

Does anyone have any guidance? Is this a bug or am I not understanding this API? Any information or work arounds would be greatly appreciated.


I've made a sample project that demonstrates this issue, which you can grab from GitHub at https://github.com/nyousefi/KeyPressSample. To see this in action, run the sample project and start pressing keys. The hardware keyboard will print the key press at the top of the screen (above the text view), while the software keyboard won't.

Answered by Frameworks Engineer in 799322022

This behaves as intended. pressesBegan is intended to be used for hardware keyboard presses. For example, you might use this to support WASD movement in a game, or detecting when modifier keys are held down to perform alternate actions in a Mac Catalyst app.

The software keyboard is intended to be used for text editing/typing, and does not send hardware keyboard events the same way.

If you're still interested in these events from software keyboard presses, I'd be interested in hearing your use case (in a feedback report, of course).

This behaves as intended. pressesBegan is intended to be used for hardware keyboard presses. For example, you might use this to support WASD movement in a game, or detecting when modifier keys are held down to perform alternate actions in a Mac Catalyst app.

The software keyboard is intended to be used for text editing/typing, and does not send hardware keyboard events the same way.

If you're still interested in these events from software keyboard presses, I'd be interested in hearing your use case (in a feedback report, of course).

It is incredibly disappointing to hear that Apple has intentionally made an API behavior inconsistent and unreliable, not only on iOS but also between iOS and macOS.

For example, we rely on intercepting the return key to automatically uppercase certain lines, know when to do additional text processing, and modify default text attributes. We also rely on key press interception to update metadata for other purposes based on which key was pressed.

All this works perfectly with the hardware keyboard, AND we can reuse the same code on macOS (it actually originated on macOS). But now I have to rewrite all of this and figure out how to keep things working because Apple has determined that hitting a key on the software keyboard should do something different than when that same key is pressed on a hardware keyboard.

This is the kind of frustration those of us who have tried to build productivity apps on iOS regularly encounter.

UITextView's pressesBegan isn't triggered by the software keyboard
 
 
Q