我正在尝试在搜索栏中实施位置建议。我可以得到所有建议,但是当用户使用键盘Enter或单击鼠标选择完成时,我无法查明。
问题是用户需要按Enter键选择完成(dismiss完成菜单窗口),然后再次按Enter键以将其提交给最新用户。我希望避免再次按下Enter键。
“发送完整字符串”模式的自动补全功能已关闭,因此无法进行。
如何在NSSearchField上检测自动完成选择?还是如何通过“发送整个搜索字符串”来触发自动补全?
PS:可能会使用未记录的通知NSTextViewDidBeginDisplayingCompletions,NSTextViewDidEndDisplayingCompletions。
- (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;
}