我有一个NSTextView
子类(Obj-C),它通过标准机制实现完成(实现completionsForPartialWordRange:indexOfSelectedItem:
和rangeForUserCompletion
等)。在过去,AppKit使用以下两种用户操作之一自动调用完成:按下command-。 (命令周期),或按esc(转义)。我刚刚换到新的" 2016年末" MacBook Pro,同时从10.11升级到10.12。代码完成不再适用于我的应用。我只是从响应者链的深处接到一个NSBeep()
的电话,当没人响应那些按键时。 NSTextView
' complete:
方法永远不会被命中(调试器说)。
我怀疑这是因为Apple改变了。我注意到complete:
(https://developer.apple.com/reference/appkit/nstextview/1449359-complete?language=objc)的文档发生了变化;曾经有人说complete:
是由esc
触发的,但现在它说它是由F5
触发的(在我的机器上似乎也不起作用,但功能键映射是总是奇怪而且难以理解,所以谁知道呢。
我通过覆盖doCommandForSelector:
进行了一些调查,只是打印AppKit正在尝试的选择器,然后调用super。事实证明,现在按esc
会导致使用doCommandForSelector:
和cancelOperation:
调用cancel:
,然后按下命令 - 。现在导致cancel:
。这是有道理的,因为这些键用于取消面板等,但这里没有涉及面板,没有取消的操作等等。
我的问题是:对我来说,回归旧行为的最佳途径是什么?换句话说,在10.12及更高版本中,我仍然需要esc
和命令 - 。在我的应用中调用complete:
。我找到了关于通过plist文件更改键绑定的Apple的文档,但这似乎不太可能是正确的方法。也许我应该做keyDown:
覆盖,但我认为由于关键事件的合并,国际键盘上的关键代码的解释等的复杂性,这些都是沮丧的;我的理解是,在事件处理中干预通常太低了。相反,我认为我应该以某种方式修改interpretKeyEvents:
的行为,将我想要的键绑定到complete:
,但我无法弄清楚如何在代码中执行此操作。
答案 0 :(得分:0)
这是一个覆盖keyDown:
以使密钥绑定有效的答案。但正如问题所述,我不确定这是正确/推荐的做事方式。
- (void)keyDown:(NSEvent *)event
{
NSString *chars = [event charactersIgnoringModifiers];
NSEventModifierFlags flags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
if ([chars length] == 1)
{
unichar keyChar = [chars characterAtIndex:0];
if ((keyChar == 0x1B) && (flags == 0))
{
// escape key pressed
[self doCommandBySelector:@selector(complete:)];
return;
}
if ((keyChar == '.') && (flags == NSEventModifierFlagCommand))
{
// command-. pressed
[self doCommandBySelector:@selector(complete:)];
return;
}
}
[super keyDown:event];
}
如果有人给出了更好的答案,我会很乐意选择它。
答案 1 :(得分:0)
在Sierra,重点组合' opt-esc'已取代' esc'作为complete:
的标准绑定。正如您所观察到的那样,未经修改的“esc”'现在绑定到cancelOperation:
。对于我的应用程序,我记录了新的行为,而不是覆盖它,因为我怀疑Apple有理由做出如此烦人的改变。