1

在 Cocoa 中,keyDown 和 keyUp 有一个可覆盖的函数,但没有 keyHeld?它是否具有功能或是否可以像在 Win32 中一样检查键状态?

这可能是一个愚蠢的问题,但我的经验有限,而且我来自 Win32 背景。

谢谢你的时间

4

2 回答 2

2

我不确定 keyHeld 在 win32 上做了什么,但是当键被按住时,keyDown 事件在 Cocoa 中重复。重复之前的速率和延迟取决于用户设置(您可以使用+keyRepeatInterval+keyRepeatDelay方法获取当前值NSEvent)。如果事件是第一个 keyDown 或具有事件isARepeat属性的重复事件,您可以捕获。

我不相信有一种方法可以检查 Cocoa 中的键状态。如果您绝对需要它,也许您会更幸运地使用较低级别的 API。如果您只需要几个键,您可能可以在 keyDown 上设置一个标志并在 keyUp 上重置它。

于 2012-10-25T17:44:21.220 回答
0

您可以为此使用计时器。当您收到按键按下事件时,请创建一个计时器,其时间间隔为您定义“按住”,如果您获得同一按键的按键按下事件,则将其销毁。如果计时器触发,则该键被按住指定的时间。

大致是这样的:

- (void)keyDown: (NSEvent *)event
{
    NSTimer * tim = [NSTimer scheduledTimerWithTimeInterval:kKeyHeldInterval 
                                                     target:self 
                                                   selector:@selector(keyHeld:) 
                                                   userInfo:event 
                                                    repeats:NO];

    NSNumber * keyCodeNum = [NSNumber numberWithUnsignedShort:[event keyCode]];
    [[self dictionaryOfKeyHeldTimers] setObject:tim forKey:keyCodeNum];
}

- (void)keyUp: (NSEvent *)event
{
    NSNumber * keyCodeNum = [NSNumber numberWithUnsignedShort:[event keyCode]];
    NSTimer * tim = [[self dictionaryOfKeyHeldTimers] popObjectForKey:keyCodeNum];

    [tim invalidate];
}

- (void)keyHeld: (NSTimer *)tim
{
    // Key was held, take action.
    NSEvent * event = [tim userInfo];
    NSNumber * keyCodeNum = [NSNumber numberWithUnsignedShort:[event keyCode]];
    [[self dictionaryOfKeyHeldTimers] removeObjectForKey:keyCodeNum];
}
于 2012-10-25T18:04:27.957 回答