MapView与本地搜索

我有一个关于在Apple地图中进行本地搜索的问题,我已将其应用到我的应用程序中。 应用程序应该向用户显示他周围的“超市”。 我的mapView也显示了用户的当前位置,但我真的不知道应该如何使用市场位置的结果。 也许Apple为此提供了解决方案/建议。 提前致谢。

结果(超市)应显示在此图片中

结果(超市)应显示在此图片中。

更新:该function工作正常但是也可以使这些引脚可点击以显示有关此位置的信息表,如下图所示?

在此处输入图像描述在此处输入图像描述

更新2:我对这个地图实现非常着迷,所以我想知道是否也可以获得有关当前位置的信息(如下面的屏幕截图所示)。 在此处输入图像描述

在iOS 6.1及更高版本中,您可以使用MKLocalSearch ,为您找到的每个MKMapItem对象添加注释。

 MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init]; request.naturalLanguageQuery = @"supermarket"; request.region = mapView.region; MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request]; [search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) { for (MKMapItem *item in response.mapItems) { MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init]; annotation.coordinate = item.placemark.coordinate; annotation.title = item.name; annotation.subtitle = item.placemark.title; [mapView addAnnotation:annotation]; } }]; 

如果你想要你的标注上的左右配件,你应该实现一个viewForAnnotation来添加这些附件(当然,为了工作,你必须将你的控制器定义为你的MKMapViewdelegate ):

 typedef enum : NSInteger { kCallOutAccessoryRight = 1, kCallOutAccessoryLeft } CallOutAccessoryType; - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation { if ([annotation isKindOfClass:[MKUserLocation class]]) return nil; static NSString *identifier = @"customAnnotationView"; MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; if (annotationView == nil) { annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier]; annotationView.canShowCallout = YES; annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; annotationView.rightCalloutAccessoryView.tag = kCallOutAccessoryRight; annotationView.leftCalloutAccessoryView = ...; // whatever you want for the left button annotationView.leftCalloutAccessoryView.tag = kCallOutAccessoryLeft; } else { annotationView.annotation = annotation; } return annotationView; } 

并且,您可能想要响应用户点击这些标注:

 - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { if (control.tag == kCallOutAccessoryRight) { NSLog(@"Present info sheet for %@ here", [view.annotation title]); } else if (control.tag == kCallOutAccessoryLeft) { NSLog(@"Do whatever you want if left accessory tapped"); } } 

您询问了如何显示用户说明。 是的,您可以通过将MKMapItem传递给MKMapItemopenMapsWithItems 。 但是这假定您从本地搜索中保存MKMapItem 。 为此,您需要创建自定义注释。 例如:

 // MapItemAnnotation.h #import  #import  @interface MapItemAnnotation : NSObject  @property (nonatomic, strong, readonly) MKMapItem *item; - (id)initWithMapItem:(MKMapItem *)item; - (NSString *)title; - (NSString *)subtitle; - (CLLocationCoordinate2D)coordinate; @end 

 // MapItemAnnotation.m #import "MapItemAnnotation.h" @implementation MapItemAnnotation - (id)initWithMapItem:(MKMapItem *)item { self = [super init]; if (self) { _item = item; } return self; } - (NSString *)title { return _item.name; } - (NSString *)subtitle { return _item.placemark.title; } - (CLLocationCoordinate2D)coordinate { return _item.placemark.coordinate; } @end 

完成后,您将注释添加到地图中的过程略有简化:

 [search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) { for (MKMapItem *item in response.mapItems) { MapItemAnnotation *annotation = [[MapItemAnnotation alloc] initWithMapItem:item]; [mapView addAnnotation:annotation]; } }]; 

但是,现在,您的左侧标注附件可以轻松启动Apple地图中的路线:

 - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { if (control.tag == kCallOutAccessoryRight) { NSLog(@"Present info sheet for %@ here", [view.annotation title]); } else if (control.tag == kCallOutAccessoryLeft) { // request directions from Apple Maps MapItemAnnotation *annotation = view.annotation; NSAssert([annotation isKindOfClass:[MapItemAnnotation class]], @"Annotation should be MapItemAnnotation: %@", annotation); [annotation.item openInMapsWithLaunchOptions:@{MKLaunchOptionsMapCenterKey : [NSValue valueWithMKCoordinate:mapView.region.center], MKLaunchOptionsMapSpanKey : [NSValue valueWithMKCoordinateSpan:mapView.region.span], MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving}]; } } 

关于更新用户位置描述,您可以定义didUpdateUserLocation方法(即每次用户位置更改时,地图视图都会调用此MKMapViewDelegate方法)。 看起来您想更新用户位置的字幕:

 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation { [self updateSubtitleForUserLocation:userLocation]; } 

这将调用此方法来执行反向地理编码并相应地更新字幕:

 - (void)updateSubtitleForUserLocation:(MKUserLocation *)userLocation { if ([self.geocoder isGeocoding]) [self.geocoder cancelGeocode]; [self.geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray *placemarks, NSError *error) { MKPlacemark *placemark = placemarks[0]; userLocation.subtitle = placemark.name; }]; } 

显然,您需要一个类属性:

 @property (nonatomic, strong) CLGeocoder *geocoder; 

你需要实例化它,例如viewDidLoad可以:

 self.geocoder = [[CLGeocoder alloc] init]; 

如果用户的位置变化超过x米(你不想做太多反向地理编码请求,你会杀掉用户的电池),我可能会稍微改进一下,只做反向地理编码,但希望这说明这个想法。