UIKeyCommand should allow action upon release of a key

Originator:alex.hamilton
Number:rdar://32972223 Date Originated:25/06/2017
Status: Resolved:
Product:IOS (UIKit) Product Version:10 (7.0+)
Classification:Suggestion Reproducible:
 
Summary:
On iOS, it is somewhat difficult to perform an action upon release of a keyboard key. It can be done, but it requires relying upon the fact that the responder's keyCommands property is queried when a key is released (i.e. the function call has to be in this property getter; I'll put an example below). This should be made officially supported with a nicer API — while it may seem like a bit of an edge case, doing this enables the user to prepare for something and begin when they are ready rather than have it start when they aren't expecting it, which can be crucial for i.e. timer apps.

Steps to Reproduce:
1. Leverage the UIKeyCommand API to configure an action to be performed upon release of a key.
2. Press and hold the key in question.

Expected Results:
There should be a clean configuration to allow the performance of an action only after the release of a key.

Observed Results:
I instead watch in dismay as the target action is triggered repeatedly and am forced to put the actual logic in the getter for keyCommands, which is definitely not where it belongs, simply to get this functionality to work.

Version:
iOS 10 for sure, but I'm almost certain this has been around for as long as UIKeyCommand has (iOS 7, I believe).

Notes:
Here's some example code I used.

    var spaceBarIsDown = false
    
    func spaceBarPressed(command: UIKeyCommand) {
        if activeTimer != nil { // We're in the middle of an attempt
            startOrStopAsNeeded()
        } else {
            button.isEnabled = false
            spaceBarIsDown = true
        }
    }
    
    override var keyCommands: [UIKeyCommand]? {
        if spaceBarIsDown {
            startOrStopAsNeeded()
            spaceBarIsDown = false
            button.isEnabled = true
        }
        let newCommand = UIKeyCommand(input: " ", modifierFlags: [], action: #selector(spaceBarPressed(command:)), discoverabilityTitle: "Start/Stop")
        return [newCommand]
    }

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!