How to force NSSearchField to send an action when autocomplete?

This question seems simple, but I tried everything I could come up with and googled for hours.

I have an NSSearchField that does autocomplete, basically copying Apple SearchField sample code . I turned off "Send an entire search string" in IB because I don’t want to search until the user completes their text recording and doesn’t want to do several searches (they are expensive).

As the user enters the field when they press the enter key, indicating that they accept the current autocomplete, I want the action for NSSearchField to fire. Instead, it simply fills in the autocomplete, then the user must click a second time to activate the action. Basically, consider starting to enter the URL in Safari, it will autocomplete, and pressing enter starts loading the page (launching the action). They don’t need to click a second time to start loading the page.

Things I tried without success:

  • control: textView: commandSelector :, looks for insertNewline :. This does not work when they press enter to complete autocomplete.
  • Override control: TextDidEndEditing :. Same as above.

Any ideas? Thanks!

+7
source share
1 answer

I figured out how to do it.

You need to override NSFieldEditor for NSTextViews.

To provide an overridden version in an NSWindow delegate:

- (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 is an instance variable. Here is the definition:

 @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 

The key part is NSReturnTextMovement after [super insertCompletion ...].

The first part will change it so that entering a space will not perform autocompletion, which was done by me in a comment: How to prevent NSSearchField from overwriting the entered lines using the first entry in the autocomplete list?

+5
source

All Articles