Захват клавиш "вверх" и "вниз", нажатых в NSTextField

Я пишу приложение "Агент" Cocoa, где у меня есть TextField в меню значков состояния, оно выглядит так:

http://s3.ifotos.pl/img/Zrzut-ekr_hwaqnwa.png

Когда вы используете шагомер, значение inc//уменьшается на 5. Я хочу, чтобы при фокусировке текстового поля и нажатии клавиш "вверх" или "вниз" то же самое происходит - значение увеличивается или уменьшается на 5.

Я уже понял, что мне нужно использовать - (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector протокола NSControlTextEditingDelegate.

Но я действительно смущен, как я это делаю. Обычно я просто делал sth.delegate = self;, и здесь я просто не знаю. Недружелюбный язык документации Apple и мой плохой английский не помогают мне. Я попытался найти ответ, но все люди указали на control:textView:..., и мои способности Google-поиска не удались, когда я хотел выяснить, как я использую этот метод делегата.

Большое спасибо. Пожалуйста, не бить меня;)

Ответ 1

Вам нужно создать объект, который будет служить делегатом текстового поля. Это можно сделать либо в коде, либо, если это кажется уместным, в Interface Builder. У вас, вероятно, уже есть контроллер, ответственный за это поле и шаговый контроль, так что это хороший кандидат. Этот объект делегата - это то, что нужно реализовать, о котором вы говорили:

- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector

Этот метод будет вызываться всякий раз, когда текстовый редактор * для текстового поля предлагается выполнить один из NSResponder сообщения о действиях. Редактор поля запрашивает его делегат, который является текстовым полем, что он должен делать, и поле, в свою очередь, запрашивает его делегат, который является вашим объектом.

Аргумент commandSelector содержит имя сообщения о действии. Поэтому вы можете проверить интересующие вас сообщения (moveUp: и moveDown: в этом случае) и перехватить их. Вы выполняете любые действия, которые вам нравятся, и не позволяйте редактору поля или текстовому полю действовать в сообщении.

- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor 
  doCommandBySelector:(SEL)commandSelector {
    if( commandSelector == @selector(moveUp:) ){
        // Your increment code
        return YES;    // We handled this command; don't pass it on
    }
    if( commandSelector == @selector(moveDown:) ){
        // Your decrement code
        return YES;
    }

    return NO;    // Default handling of the command

} 

* Вкратце, NSTextView, который обрабатывает ввод от имени текстового поля при активном поле.

Ответ 2

Попробуйте переопределить сообщение NSResponder следующим образом:

- (BOOL)performKeyEquivalent:(NSEvent *)theEvent{
    switch ([[theEvent charactersIgnoringModifiers] characterAtIndex:0]) {
        case NSUpArrowFunctionKey:
            // Increase by 5 here
            return YES;
            break;
        case NSDownArrowFunctionKey:;
            // Decrease by 5 here
            return YES;
            break;
        default:
            break;
    }
    return [super performKeyEquivalent:theEvent];
}

Ответ 3

если вы хотите записать ярлыки, вы также можете использовать такой код:

- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {

NSEvent *currentEvent = [[NSApplication sharedApplication]currentEvent];
if ((currentEvent.modifierFlags & NSCommandKeyMask) && (currentEvent.keyCode == kVK_Return)) {  //command + enter to confirm
    //do what you want
    return YES;
}
return NO;
}