Что ж, у меня есть кладж.
Я добавил логическое свойство shouldSwallowThisReturn. И я добавил строку, которая устанавливает для этого логического значения yes в селекторе отправленных действий текстового поля:
switch (self.iNavMode) {
case kNavModeNeutral:
break;
case kNavModeSaveAndNew:
[self.window makeFirstResponder:self.btnSaveAndNew];
self.shouldSwallowThisReturn = YES;
[self.btnSaveAndNew setKeyEquivalent:@"\r"];
break;
case kNavModeSaveAndNext:
[self.window makeFirstResponder:self.btnSaveAndNext];
self.shouldSwallowThisReturn = YES;
[self.btnSaveAndNext setKeyEquivalent:@"\r"];
break;
default:
break;
}
И я добавил к действию выбранной кнопки несколько строк:
if (self.shouldSwallowThisReturn) {
self.shouldSwallowThisReturn = NO;
return;
}
[self.btnSaveAndNext setKeyEquivalent:@""];
Таким образом, остальная часть действия кнопки выполняется только после того, как пользователь нажмет клавишу возврата во второй раз.
Это работает, но я бы предпочел более элегантное решение.
Дальнейшее изучение руководства Apple по обработке событий показывает, что не так: по-видимому, когда вы используете IB для назначения отправленного действия текстовому полю, хотя действие отключается, когда пользователь нажимает return, это return не регистрируется как эквивалент ключа. , и поэтому не отвечает «да» на запрос performKeyEquivalent приложения, и поэтому приложение продолжает искать элемент управления, который отвечает «да», поэтому в итоге оно вызывает кнопку самостоятельно.
Итак, кажется, что мне действительно нужно создать подкласс текстового поля и переопределить его метод performKeyEquivalent, чтобы он возвращал yes, если keyCode равен 36 (код для клавиши возврата), например:
- (BOOL) performKeyEquivalent:(NSEvent *)theEvent {
printf("\nThe keycode is %d", [theEvent keyCode]);
if ([theEvent keyCode] == 36)
return YES;
else
return NO;
}
Но происходит то, что метод переопределения вызывается, даже если целевое текстовое поле не имеет фокуса. Действительно, он вызывается, даже когда выбранная кнопка уже является firstResponder. Итак, теперь возврат пользователя всегда прерывается, а действие кнопки никогда не вызывается.
Я изменил метод переопределения, чтобы проверить личность firstResponder:
- (BOOL) performKeyEquivalent:(NSEvent *)theEvent {
printf("\nThe keycode is %d", [theEvent keyCode]);
if ([theEvent keyCode] == 36) {
ThisProject_AppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
id firstResponder = [appDelegate.windowController.window firstResponder];
if ([firstResponder isKindOfClass:[NSTextView class]]) {
printf("\nfirstResp is a field editor, a textview.");
if ([firstResponder delegate] == self) {
printf("\ntarget textfield is firstResponder.");
return YES;
}
}
else if ([firstResponder isKindOfClass:[NSButton class]]) {
printf("\nfirstResp is a button.");
return YES;
}
}
return NO;
}
Оказывается, переопределение вызывается после выполнения действия send-action текстового поля, когда статус firstResponder уже был передан кнопке. Так что переопределение не помогает.
На данный момент я застрял с клуджем в верхней части этого ответа. Но должен быть какой-то способ получить отправленное действие, чтобы полностью захватить событие клавиши возврата, которое его вызвало ...
person
Wienke
schedule
23.02.2011
[self.searchTextField.cell setSendsActionOnEndEditing:NO]
, чтобы дважды не получить свое действие. - person nielsbot   schedule 03.12.2013