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

#cocoa #keyboard-events

#какао #клавиатура-события #cocoa

Вопрос:

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

Ответ №1:

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

Комментарии:

1. Вы также должны быть ответчиком и находиться в цепочке ответчиков. Представление, которое принимает first responder, является хорошим способом выполнить это предварительное условие.

2. Коды клавиш были одинаковыми с незапамятных времен и вряд ли изменятся. Смотрите эту информативную статью Питера Хоси. Тот факт, что они видны нам только в заголовке Carbon, мало что значит. CGEvents используют их в первую очередь, а не соответствующий Юникод.

3. @Josh ОК. Я понял. Но я не смог найти определенные значения констант ключевого кода. Для надежного его использования требуется какая-то спецификация. Могу ли я узнать, где находится официальная спецификация?

4. @Eonil: пожалуйста, поймите, что я не говорил, что в вашем методе вообще что-то не так. Я просто хотел представить другое.

5. @Eonil: Только что наткнулся на довольно недавнюю ветку Cocoa-dev , в которой говорится об устаревании / не-устаревании различных частей Carbon. Это прояснило для меня несколько вещей; подумал, что вам может быть интересно. Итог таков: графический интерфейс Carbon не работает, почти все остальное по-прежнему в порядке, документация должна отражать это, но не делает такой хорошей работы.

Ответ №2:

В моем случае я хотел, чтобы представленный подкласс 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];
  

Комментарии:

1. Это очень полезный API для некоторых крайних случаев, когда цепочка ответчиков не выполняет то, что вы хотите.