Обнаружение автозаполнения в NSSearchField - PullRequest
0 голосов
/ 08 ноября 2018

Я пытаюсь реализовать предложения по местоположению в поле поиска. Я могу получить все предложения, однако я не могу узнать, когда пользователь выбирает завершение, используя ввод с клавиатуры или щелчок мышью.

Проблема заключается в том, что пользователю необходимо нажать клавишу ввода, чтобы выбрать завершение (окно меню "Завершение завершения"), и снова нажать клавишу ввода, чтобы отправить его в последнее время. Я хотел бы избежать второго нажатия Enter.

Автозаполнение отключено для режима «отправка всей строки», так что это не ход.

Как определить выбор автозаполнения в NSSearchField? Или как вызвать автозаполнение с помощью «отправляет всю строку поиска»?

PS: есть недокументированные уведомления NSTextViewDidBeginDisplayingCompletions, NSTextViewDidEndDisplayingCompletions, которые могут использоваться.

autocomplete nssearchfield

- (void)windowDidLoad {
    [super windowDidLoad];

    MKLocalSearchCompleter *searchCompleter = [[MKLocalSearchCompleter alloc] init];
    searchCompleter.filterType = MKSearchCompletionFilterTypeLocationsOnly;
    searchCompleter.delegate = self;
    [self setSearchCompleter:searchCompleter];

    [[NSNotificationCenter defaultCenter] addObserverForName:@"NSTextViewDidEndDisplayingCompletions" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        self.displayingCompletions = YES;
    }];

    [[NSNotificationCenter defaultCenter] addObserverForName:@"NSTextViewDidEndDisplayingCompletions" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        self.displayingCompletions = NO;
        if ([[self searchCompleter] isSearching] == NO) {
            [self search:nil];
        }
    }];
}

- (void)completerDidUpdateResults:(MKLocalSearchCompleter *)completer
{
    [self setSearchAutocompletions:[completer results]];
    [self displayAutocompletions];
}

- (void)completer:(MKLocalSearchCompleter *)completer didFailWithError:(NSError *)error
{
    if (error) {
        NSLog(@"%@",error);
    }
}

- (IBAction)autocompleteSearch:(NSSearchField *)sender
{
    if ([[sender stringValue] length] < 3) {
        return;
    }
    if (self.isDisplayingCompletions) {
        return;
    }
    NSString *searchString = [sender stringValue];
    [[self searchCompleter] cancel];
    [[self searchCompleter] setQueryFragment:searchString];
}



- (void)displayAutocompletions
{
    if (self.isSearching && !self.completePosting) {
        _completePosting = YES;
        [[[self window] fieldEditor:YES forObject:[self searchField]] complete:nil];
        _completePosting = NO;
    }
}

- (void)controlTextDidEndEditing:(NSNotification *)obj
{
    [self search:nil];
}

- (void)search:(id)sender
{
    NSString *searchString = [[self searchField] stringValue];
    if ([searchString length] <= 3) {
        return;
    }
    MKLocalSearchCompletion *completionToSearch;
    NSArray<MKLocalSearchCompletion *> *results = [[self searchCompleter] results];
    for (MKLocalSearchCompletion *completion in results) {
        if ([[completion title] isEqualToString:searchString]) {
            completionToSearch = completion;
            break;
        }
    }
//    MKCoordinateRegion boundingRegion = [[self mapView] region];
    MKLocalSearchRequest *request;
    if (completionToSearch) {
        request = [[MKLocalSearchRequest alloc] initWithCompletion:completionToSearch];
    } else {
        request = [[MKLocalSearchRequest alloc] init];
        [request setNaturalLanguageQuery:searchString];
    }
    //[request setRegion:boundingRegion];
    [[self localSearch] cancel];
    MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:request];
    [self setLocalSearch:localSearch];
    [localSearch startWithCompletionHandler:^(MKLocalSearchResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            NSLog(@"%@", error);
        } else {
            [[self mapView] setRegion:[response boundingRegion]];
            MKMapItem *item = [response.mapItems firstObject];
            [[self searchField] setStringValue:[item name]];
            MKPlacemark *placemark = [item placemark];

            if (placemark) {
                CLLocationCoordinate2D coordinate = placemark.coordinate;
                NSLog(@"%@", placemark);
            }
        }
    }];

}

#pragma mark NSControlTextEditingDelegate

- (NSArray *)control:(NSControl *)control textView:(NSTextView *)textView completions:(NSArray *)words forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(NSInteger *)index
{
    NSMutableArray *matches = [[NSMutableArray alloc] init];
    for (MKLocalSearchCompletion *completion in [self searchAutocompletions]) {
            [matches addObject:[completion title]];
    }
    *index = -1;
    return matches;
}

#pragma mark NSSearchFieldDelegate

- (void)searchFieldDidStartSearching:(NSSearchField *)sender
{
    _searching = YES;
}

- (void)searchFieldDidEndSearching:(NSSearchField *)sender
{
    _searching = NO;
}
...