Как заставить NSSearchField отправлять действие при автозаполнении? - PullRequest
7 голосов
/ 02 марта 2011

Этот вопрос кажется простым, но я перепробовал все, что мог придумать, и гуглил в течение нескольких часов.

У меня есть NSSearchField, который выполняет автозаполнение, в основном копируя образец кода SearchField от Apple .Я отключил «Отправляет строку поиска целиком» в IB, поскольку не хочу выполнять поиск до тех пор, пока пользователь не завершит ввод текста, и не хочу выполнять многократный поиск (они дорогие).

Когда пользователь печатает в поле, когда он нажимает клавишу ввода, указывая, что он принимает текущее автозаполнение, я хочу, чтобы действие для NSSearchField сработало.Вместо этого он просто заполняет автодополнение, а затем пользователь должен нажать клавишу ввода еще раз, чтобы запустить действие.По сути, подумайте о том, чтобы начать вводить URL-адрес в Safari, он автоматически заполняется, и нажатие клавиши Enter запускает загрузку страницы (запускает действие).Им не нужно нажимать ввод во второй раз, чтобы начать загрузку страницы.

Вещи, которые я безуспешно пробовал:

  • control: textView: commandSelector :, ищу insertNewline:.Он не срабатывает, когда они нажимают Enter, чтобы завершить автодополнение
  • Переопределение controlTextDidEndEditing :.То же, что и выше

Есть идеи?Спасибо!

1 Ответ

6 голосов
/ 19 марта 2011

Я разобрался, как заставить это работать.

Вам необходимо переопределить NSFieldEditor для NSTextViews.

Чтобы предоставить переопределенную версию, в делегате 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;
}

_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

Ключевой частью является NSReturnTextMovement после [super insertCompletion ...].

Первая часть изменит его так, что ввод пробела не будет выполнять автозаполнение, что я и сделал: Как запретить NSSearchField перезаписывать введенные строки, используя первую запись в списке автозаполнения?

...