如何让NSSearchField在自动完成时发送动作?

Jer*_*emy 7 cocoa autocomplete objective-c nstextfield nssearchfield

这个问题似乎很简单,但我已经尝试了我能想到的一切,并用Google搜索了几个小时.

我有一个自动完成的NSSearchField,基本上复制了Apple的SearchField示例代码.我在IB中关闭了"发送整个搜索字符串",因为我不想在用户完成文本输入之前进行搜索,并且不想进行多次搜索(它们很昂贵).

当用户在字段中键入时,当他们按Enter键,指定他们接受当前的自动完成时,我希望触发NSSearchField的操作.相反,它似乎只是填写自动完成,然后用户必须再次按下输入才能触发操作.基本上,考虑开始在Safari中输入URL,它会自动填充,然后按Enter键开始加载页面(触发操作).他们不需要再次按回车键开始加载页面.

我尝试过的事情没有成功:

  • control:textView:commandSelector:,查找insertNewline:.当他们按Enter键完成自动完成时,它不会被触发
  • 覆盖controlTextDidEndEditing:与上述相同

有任何想法吗?谢谢!

Jer*_*emy 6

我想出了如何使这项工作.

您需要覆盖NSTextViews的NSFieldEditor.

要在NSWindow的代表中提供重写版本:

- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client
{
    if ([client isKindOfClass:[NSSearchField class]])
    {
        if (!_mlFieldEditor)
        {
            _mlFieldEditor = [[MLFieldEditor alloc] init];
            [_mlFieldEditor setFieldEditor:YES];
        }
        return _mlFieldEditor;
    }
    return nil;
}
Run Code Online (Sandbox Code Playgroud)

_mlFieldEditor是一个实例变量.这是定义:

@interface MLFieldEditor : NSTextView
@end

@implementation MLFieldEditor


-  (void)insertCompletion:(NSString *)word forPartialWordRange:(NSRange)charRange movement:(NSInteger)movement isFinal:(BOOL)flag
{
    // suppress completion if user types a space
    if (movement == NSRightTextMovement) return;

    // show full replacements
    if (charRange.location != 0) {
        charRange.length += charRange.location;
        charRange.location = 0;
    }

    [super insertCompletion:word forPartialWordRange:charRange movement:movement isFinal:flag];

    if (movement == NSReturnTextMovement)
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:MLSearchFieldAutocompleted object:self userInfo:nil];
    }
}

@end
Run Code Online (Sandbox Code Playgroud)

关键部分是[super insertCompletion ...]之后的NSReturnTextMovement.

第一部分将更改它,以便键入空格键将不会执行自动完成,这是我所做的评论: 如何防止NSSearchField使用第一个自动完成列表条目覆盖输入的字符串?