Как обработать событие со стрелкой в ​​приложении Какао? - PullRequest
12 голосов
/ 14 мая 2011

Как обработать событие со стрелкой в ​​приложении Какао?

Ответы [ 3 ]

16 голосов
/ 15 мая 2011

Но, но, но ... Я не хочу быть 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

Руководство по обработке событий дает некоторыевозможные варианты использованияКажется, что это дружественная версия CGEventTap для Какао или способ обойти цепочку респондента для какой-то конкретной цели.Существует ограниченный выбор типов событий, которые можно отслеживать, например, только клавишей вниз, а не вверх. документы имеют список.

Также доступно: проверка событий, поступающих в любое другое приложение (без возможности их изменения), используя addGlobalMonitorForEventsMatchingMask:handler:.Как и события, этот метод требует, чтобы Accessibility был включен.

11 голосов
/ 14 мая 2011

Смотрите этот код.Я предположил, что класс является подклассом 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.

3 голосов
/ 11 декабря 2015

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

Определить монитор событий (необязательно), может быть локально в вашем подклассе 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];
...