嗯,我有一個kludge。
我添加了一個boolean屬性shouldSwallowThisReturn。我補充說,設置這個布爾值是在文本框的發送動作選擇線路:
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:@""];
所以其餘按鈕的動作僅在用戶第二次按下返回後執行。
這可行,但我更喜歡更優雅的解決方案。
蘋果的事件處理指南進一步審查表明,什麼是錯的:顯然,當你使用IB來分配一個發送的行動到一個文本字段,雖然當用戶按下返回時,該動作被設置,該返回不會註冊作爲一個關鍵等價物,因此對應用程序的performKeyEquivalent查詢沒有迴應,因此應用程序一直在尋找一個能夠回答yes的控件,因此最終它會自行調用該按鈕。
這樣看來我真的應該做的是子類的文本框,並使其返回是,如果鍵代碼爲36(爲返回鍵代碼)重寫其performKeyEquivalent方法,像這樣:
- (BOOL) performKeyEquivalent:(NSEvent *)theEvent {
printf("\nThe keycode is %d", [theEvent keyCode]);
if ([theEvent keyCode] == 36)
return YES;
else
return NO;
}
但是會發生的是,即使目標文本字段沒有焦點,也會調用覆蓋方法。事實上,即使所選按鈕已經是第一個響應者,它也會被調用。所以現在用戶的返回總是被搶佔,並且按鈕的動作從不被調用。
我修改了覆蓋方法來檢查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;
}
原來的倍率後調用文本字段的發送動作的執行過程中,firstResponder狀態早已當已被轉移到按鈕。所以重寫不起作用。
現在,我在這個答案的頂部卡住了kludge。但必須有一些方法來獲得一個發送動作,以完全捕獲返回鍵事件,將其設置爲關閉...
我發現這個問題也發生了 - 原來改變IB上的「發送操作」菜單項檢查員調色板不起作用。我不得不手動調用'[self.searchTextField.cell setSendsActionOnEndEditing:NO]'來避免兩次執行我的操作。 – nielsbot 2013-12-02 22:31:20
謝謝。這可能是比我接受的答案更好的解決方案。 – Wienke 2013-12-24 19:27:11