Detecting continuous key presses with UIKeyCommand

Pro tip - my arrow keys were blocked because I'd returned false from

-(BOOL) canPerformAction:(SEL)action withSender:(id)sender 

Make sure to check for your own selectors you've created.


Seems that this is indeed not possible in iOS 7.


It is possible to get continuous key presses since the method keyCommands is first called when you press a key on the keyboard, then called again after the key has been released. However, you can't tell if the user is releasing a key or pressing another key while still holding down the first key, so there are limitations to what you can do.

This limitation should be fine as long as your app does not require that the user can press and hold multiple keys at the same time. If you can assume that the user is only pressing one key at a time, you can use this to get continuous key presses.

EDIT: I got the comment that this is seems to be a false statement. That is wrong! Here is a complete example:

#import "ViewController.h"

@interface ViewController ()
{
    bool keyDown;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    keyDown = NO;
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (NSArray*)keyCommands
{
    if(keyDown==YES) {
        printf("Key released\n");
        keyDown = NO;
    }
    UIKeyCommand *upArrow = [UIKeyCommand keyCommandWithInput:UIKeyInputUpArrow
                                                modifierFlags:0
                                                       action:@selector(upArrow:)];
    return @[upArrow];
}

-(void)upArrow:(UIKeyCommand*)keyCommand
{
    printf("Key pressed\n");
    keyDown = YES;
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}
@end

When you press the up-arrow button, you will see the text "Key pressed" in the output console. When you release it, you will see the text "Key released". As I mentioned, there's one limitation. If you hold the up-arrow and then at the same time press another key, the code will assume the up-arrow key has been released.

This is what happens when you press and hold the up arrow key:

  1. First of all, the method keyCommands will be called twice (why twice?)
  2. The upArrow method will be called once and the variable keyDown will be set to YES and the text "Key pressed" will be printed.

This is what happens when you release the key:

  1. The method keyCommands will be called one time. The text "Key released" will be printed since keyDown=YES.

As I mentioned above, there's a limitation with this method; if you first press up arrow and hold it while pressing another button, this code will believe that you have released the up arrow button. You obviously need to wrap this up with a timer to get continuous key presses in your app.


With iOS 13.4+ it is now possible. UIPress now has a UIKey member variable

Refer to this official tutorial