在 Cocoa 中,keyDown 和 keyUp 有一个可重写的函数,但没有 keyHeld?它有功能吗?或者有没有办法像 Win32 一样检查按键状态?
这可能是一个愚蠢的问题,但我的经验有限,而且我来自 Win32 背景。
感谢您的宝贵时间
我不确定 keyHeld 在 win32 上做什么,但是当按住键时,在 Cocoa 中会重复 keyDown 事件。重复之前的速率和延迟取决于用户设置(您可以使用
+keyRepeatInterval
上的 +keyRepeatDelay
和 NSEvent
方法获取当前值)。您可以使用事件的 isARepeat
属性来捕获事件是第一个 keyDown 还是重复事件。
我不相信有办法检查 Cocoa 中的关键状态。如果您绝对需要,也许您会更幸运地使用较低级别的 API。如果您只需要几个键,您可能可以在 keyDown 上设置一个标志并在 keyUp 上重置它。
您可以为此使用计时器。当您收到按键按下事件时,创建一个计时器,其时间间隔为您定义“按下”,并在您收到同一按键的按键按下事件时销毁它。如果计时器启动,则表示按住该键达您指定的时间。
大致是这样的:
- (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];
}