如何在Cocoa app中处理箭头键事件?
答案 0 :(得分:16)
但是,但是......但我不想成为NSResponder
子类。
@interface AMonitorNotAResponder : NSObject
@end
@implementation AMonitorNotAResponder
{
id eventMonitor; // An event monitor object; instance of
// private class _NSLocalEventObserver
}
- (id)init
{
self = [super init];
if( !self ) return nil;
NSEvent * (^monitorHandler)(NSEvent *);
monitorHandler = ^NSEvent * (NSEvent * theEvent){
switch ([theEvent keyCode]) {
case 123: // Left arrow
NSLog(@"Left behind.");
break;
case 124: // Right arrow
NSLog(@"Right as always!");
break;
case 125: // Down arrow
NSLog(@"Downward is Heavenward");
break;
case 126: // Up arrow
NSLog(@"Up, up, and away!");
break;
default:
break;
}
// Return the event, a new event, or, to stop
// the event from being dispatched, nil
return theEvent;
};
// Creates an object we do not own, but must keep track
// of so that it can be "removed" when we're done
eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask
handler:monitorHandler];
return self;
}
- (void)dealloc
{
[NSEvent removeMonitor:eventMon];
}
@end
Event Handling Guide提供了一些可能的用途。似乎是CGEventTap
的友好Cocoa版本,或者为某些特定目的绕过响应链的方法。可以监视的事件类型选择有限,例如,只有按键,而不是向上。 docs有列表。
同样可用:使用addGlobalMonitorForEventsMatchingMask:handler:
检查发往任何其他应用程序的事件(无法修改它们)。与事件点击一样,此方法需要启用“辅助功能”。
答案 1 :(得分:11)
请参阅此代码。我假设该类是NSView
的子类。
#pragma mark - NSResponder
- (void)keyDown:(NSEvent *)theEvent
{
NSString* const character = [theEvent charactersIgnoringModifiers];
unichar const code = [character characterAtIndex:0];
switch (code)
{
case NSUpArrowFunctionKey:
{
break;
}
case NSDownArrowFunctionKey:
{
break;
}
case NSLeftArrowFunctionKey:
{
[self navigateToPreviousImage];
break;
}
case NSRightArrowFunctionKey:
{
[self navigateToNextImage];
break;
}
}
}
视图应该是接收事件的第一响应者。也许这段代码需要支持。
#pragma mark - NSResponder
- (BOOL)canBecomeKeyView
{
return YES;
}
- (BOOL)acceptsFirstResponder
{
return YES;
}
要使用此方法,该类应该是NSResponder
的子类。请参阅其他答案处理,无需继承NSResponder。
答案 2 :(得分:3)
在我的情况下,我希望一个呈现的NSViewController子类能够以最小的努力收听箭头键事件以进行导航。这是我发现的最佳解决方案,Josh Caswell的答案略有不同。
定义事件监视器(可选),可以在NSViewController子类.m
中本地id keyMonitor;
然后开始监视事件,例如在viewDidLoad中。
keyMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:^(NSEvent *event) {
unichar character = [[event characters] characterAtIndex:0];
switch (character) {
case NSUpArrowFunctionKey:
NSLog(@"Up");
break;
case NSDownArrowFunctionKey:
NSLog(@"Down");
break;
case NSLeftArrowFunctionKey:
NSLog(@"Left");
break;
case NSRightArrowFunctionKey:
NSLog(@"Right");
break;
default:
break;
}
return event;
}];
在不需要时删除显示器(假设您已定义)
[NSEvent removeMonitor:keyMonitor];