NSTextView绑定完成:在macOS 10.12上打破?

时间:2017-01-23 03:38:36

标签: objective-c macos nstextview

我有一个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:,但我无法弄清楚如何在代码中执行此操作。

2 个答案:

答案 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有理由做出如此烦人的改变。