Обнаружение непрерывных нажатий клавиш с помощью UIKeyCommand

Можно ли получать непрерывные нажатия клавиш?

Я использую keyCommands: чтобы перехватить клавиши со стрелками на внешней клавиатуре, но я получаю только 1 вызов на печать. Я хотел бы получить либо несколько вызовов каждые X миллисекунды, пока клавиша удерживается, либо звонит, когда клавиша нажата, и когда ее отпустили.

Здесь мой код:

- (NSArray *)keyCommands
{
    UIKeyCommand *upArrow = [UIKeyCommand keyCommandWithInput:UIKeyInputUpArrow
                                                modifierFlags:0
                                                       action:@selector(upArrow:)];
    UIKeyCommand *downArrow = [UIKeyCommand keyCommandWithInput:UIKeyInputDownArrow
                                                  modifierFlags:0
                                                         action:@selector(downArrow:)];
    UIKeyCommand *leftArrow = [UIKeyCommand keyCommandWithInput:UIKeyInputLeftArrow
                                                  modifierFlags:0
                                                         action:@selector(leftArrow:)];
    UIKeyCommand *rightArrow = [UIKeyCommand keyCommandWithInput:UIKeyInputRightArrow
                                                   modifierFlags:0
                                                          action:@selector(rightArrow:)];
    UIKeyCommand *leftArrowCmd = [UIKeyCommand keyCommandWithInput:UIKeyInputLeftArrow
                                                     modifierFlags:UIKeyModifierCommand
                                                            action:@selector(leftArrowCmd:)];
    UIKeyCommand *rightArrowCmd = [UIKeyCommand keyCommandWithInput:UIKeyInputRightArrow
                                                      modifierFlags:UIKeyModifierCommand
                                                             action:@selector(rightArrowCmd:)];
    UIKeyCommand *lCmd = [UIKeyCommand keyCommandWithInput:@"l"
                                             modifierFlags:UIKeyModifierCommand
                                                    action:@selector(lCmd:)];
    UIKeyCommand *rCmd = [UIKeyCommand keyCommandWithInput:@"r"
                                             modifierFlags:UIKeyModifierCommand
                                                    action:@selector(rCmd:)];
    UIKeyCommand *mCmd = [UIKeyCommand keyCommandWithInput:@"m"
                                             modifierFlags:UIKeyModifierCommand
                                                    action:@selector(mCmd:)];
    return @[upArrow, downArrow, leftArrow, rightArrow, leftArrowCmd, rightArrowCmd, lCmd, rCmd, mCmd];
}

Ответы

Ответ 1

Кажется, что это действительно невозможно в iOS 7.

Ответ 2

Pro tip - мои клавиши со стрелками были заблокированы, потому что я вернул false из

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

Обязательно проверьте свои собственные селекторы.

Ответ 3

Можно получать непрерывные нажатия клавиш, так как метод keyCommands сначала вызывается, когда вы нажимаете клавишу на клавиатуре, а затем вызывается снова после того, как ключ был выпущен. Однако вы не можете сказать, освобождает ли пользователь ключ или нажимает другую клавишу, все еще удерживая первый ключ, поэтому существуют ограничения на то, что вы можете сделать.

Это ограничение должно быть прекрасным, если ваше приложение не требует, чтобы пользователь мог одновременно нажать и удерживать несколько клавиш. Если вы можете предположить, что пользователь нажимает только одну клавишу за раз, вы можете использовать ее для непрерывного нажатия клавиш.

EDIT: Я получил комментарий, что это, кажется, ложное утверждение. Это не правильно! Вот полный пример:

#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

Когда вы нажимаете кнопку со стрелкой вверх, вы увидите текст "Ключ нажат" в выходной консоли. Когда вы отпустите его, вы увидите текст "Key release". Как я уже говорил, есть одно ограничение. Если вы удерживаете стрелку вверх и затем одновременно нажимаете другую клавишу, код будет считать, что клавиша со стрелкой вверх была отпущена.

Это то, что происходит, когда вы нажимаете и удерживаете клавишу со стрелкой вверх:

  • Прежде всего, метод keyCommands будет вызываться дважды (почему дважды?)
  • Метод upArrow будет вызываться один раз, а переменная keyDown будет установлена ​​в YES и текст "Key нажата" будет напечатан.

Это то, что происходит, когда вы отпускаете ключ:

  1. Метод keyCommands будет вызываться один раз. Текст "Key release" будет напечатан, так как keyDown = YES.

Как я упоминал выше, существует ограничение с этим методом; если вы сначала нажмете стрелку и удерживаете ее, нажимая еще одну кнопку, этот код будет считать, что вы выпустили кнопку со стрелкой вверх. Вам, очевидно, нужно обернуть это таймером, чтобы получать непрерывные нажатия клавиш в вашем приложении.