点击事件MKMapView MKPointAnnotation

我有一个注释列表(MKPointAnnotation)。 我有一个UIViewController是整个视图,MKMapView实现控制器,我认为是有用的检测用户与地图的交互,我自己的MKPointAnnotation实现(子类)控制器告诉如何显示注释。

不过,我惊讶于用户检测到敲击事件。

谷歌search告诉我,我必须通过执行以下function来做些事情。

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 

还有我必须在一些实现MapViewDelegate(Protocol)的类中实现这个。

但是我都很困惑,无法前进。 谁能告诉我在哪里做什么?

对不起,大惊小怪!

有两种方式检测用户与您的注释视图的交互。 常用的技巧是定义一个标注(当你点击一个典型的地图应用程序中的一个图钉时,你看到的标准小的popup窗口泡泡)为你的MKAnnotationView 。 然后在标准viewForAnnotation方法中为注释创build注解视图:

 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { if ([annotation isKindOfClass:[MKUserLocation class]]) return nil; MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"]; annotationView.canShowCallout = YES; annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; return annotationView; } 

通过这样做,你可以得到一个标注,但是你正在添加一个正确的附件,在我上面的例子中是一个披露指标。 这样,他们点击你的注释视图(在我上面的示例中,地图上的一个图钉),他们看到标注,当他们点击标注的正确附件(本例中的小公开指示器)时,调用calloutAccessoryControlTapped被调用(在我的例子中,执行一个细节视图控制器segue):

 - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { [self performSegueWithIdentifier:@"DetailsIphone" sender:view]; } 

这是iPhone小屏幕上非常典型的用户体验。

但是,如果你不喜欢那个用户体验,并且你不想要标准标注,而是想要其他的事情发生,你可以定义你的MKAnnotationView这样标注就不会显示出来,而是拦截它并做一些事情否则(例如,在iPad地图应用程序中,您可能会显示一些更复杂的popup窗口,而不是标准的标注)。 例如,你可以让你的MKAnnotationView不显示标注:

 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { if ([annotation isKindOfClass:[MKUserLocation class]]) return nil; MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"]; annotationView.canShowCallout = NO; return annotationView; } 

但是,您可以手动处理didSelectAnnotationView以检测用户何时点击您的MKAnnotationView ,在此示例中显示一个popup窗口:

 - (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view { [mapView deselectAnnotation:view.annotation animated:YES]; DetailsViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"DetailsPopover"]; controller.annotation = view.annotation; self.popover = [[UIPopoverController alloc] initWithContentViewController:controller]; self.popover.delegate = self; [self.popover presentPopoverFromRect:view.frame inView:view.superview permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; } 

我在这里的答案中包含了上述代码生成的用户界面的一些屏幕截图。

在这个方法中添加button

 -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; pinView.canShowCallout = YES; } Then callout method - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { InfoView *infoView = [[InfoView alloc]initWithNibName:@"InfoView" bundle:nil]; [self.navigationController pushViewController:infoView animated:YES]; } 

Robs示例Swift 3:

 class MapViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Create map view in storyboard view.delegate = self } } extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "annotationView") annotationView.canShowCallout = true annotationView.rightCalloutAccessoryView = UIButton.init(type: UIButtonType.detailDisclosure) return annotationView } func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { guard let annotation = view.annotation else { return } let urlString = "http://maps.apple.com/?sll=\(annotation.coordinate.latitude),\(annotation.coordinate.longitude)" guard let url = URL(string: urlString) else { return } UIApplication.shared.openURL(url) } }