嗯,我有一个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