【问题标题】:Detecting continuous key presses with UIKeyCommand使用 UIKeyCommand 检测连续按键
【发布时间】:2014-01-28 00:55:59
【问题描述】:

是否可以连续按键?

我正在使用 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];
}

【问题讨论】:

    标签: ios keyboard keyboard-shortcuts uiresponder uikeycommand


    【解决方案1】:

    似乎这在 iOS 7 中确实是不可能的。

    【讨论】:

    • 请参阅下面的 Lars Forsberg 回答。
    • @Ron 这个“解决方案”依赖于未记录的行为,并且可能随时中断。强烈建议不要使用这种方法。
    【解决方案2】:

    有可能获得连续的按键,因为方法 keyCommands 在您按下键盘上的一个键时首先被调用,然后在该键被释放后再次调用。但是,您无法判断用户在按住第一个键的同时是释放一个键还是按下另一个键,因此您可以执行的操作受到限制。

    只要您的应用不要求用户可以同时按住多个键,此限制应该没问题。如果您可以假设用户一次只按一个键,则可以使用它来获得连续的按键。

    编辑:我得到的评论是这似乎是一个错误的陈述。那是错的!这是一个完整的例子:

    #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
    

    当您按下向上箭头按钮时,您将在输出控制台中看到文本“按下键”。当你释放它时,你会看到文本“密钥释放”。正如我所提到的,有一个限制。如果您按住向上箭头,然后同时按下另一个键,代码将假定向上箭头键已被释放。

    这是当您按住向上箭头键时发生的情况:

    1. 首先,方法keyCommands会被调用两次(为什么是两次?)
    2. upArrow 方法将被调用一次,并且变量 keyDown 将设置为 YES,并且将打印文本“Keypressed”。

    当您释放密钥时会发生以下情况:

    1. 方法 keyCommands 将被调用一次。由于 keyDown=YES,将打印文本“已释放密钥”。

    正如我上面提到的,这种方法有一个限制;如果您先按向上箭头并按住另一个按钮,则此代码将认为您已释放向上箭头按钮。你显然需要用一个计时器来结束它,以便在你的应用中获得连续的按键。

    【讨论】:

    • 这是 iOS 8 中的新功能吗?我测试时不是这种情况。
    • 这不是假的,我在我自己的应用程序 VividTracker 中有这个工作。你到底是什么意思是假的?
    • 我现在添加了一个完整的例子来证明这是可行的。您可以在模拟器中运行它。它在部署到 iOS 7.1 时也有效。
    • 我没有仔细阅读您的答案。我已经确认您所说的确实正确。我很抱歉。谢谢你的例子。
    • 此行为未记录在案,可能随时中断。
    【解决方案3】:

    专业提示 - 我的箭头键被阻止了,因为我从

    返回了 false
    -(BOOL) canPerformAction:(SEL)action withSender:(id)sender 
    

    确保检查您自己创建的选择器。

    【讨论】:

      【解决方案4】:

      现在可以使用 iOS 13.4+。 UIPress 现在有一个 UIKey 成员变量

      参考这个official tutorial

      【讨论】:

        猜你喜欢
        • 2014-03-30
        • 2013-05-10
        • 2015-10-21
        • 1970-01-01
        • 1970-01-01
        • 2016-11-17
        • 1970-01-01
        • 1970-01-01
        • 2016-09-18
        相关资源
        最近更新 更多