允许在没有标注配件视图的情况下在注释标注的任何位置点击

我有一个地图视图添加注释或多或less像这样:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation { MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"MKPinAnnotationView"]; annotationView.canShowCallout = YES; UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; [detailButton addTarget:self action:@selector(handleButtonAction) forControlEvents:UIControlEventTouchUpInside]; annotationView.rightCalloutAccessoryView = detailButton; return annotationView; } 

在iOS 7中,这会在标注的右侧放置一个“我”图标。 点击图标触发mapView:annotationView:calloutAccessoryControlTapped:在委托)和handleButtonAction:自我)。 不过,我最近意识到,你也可以点击标注的其他地方,同样的两个方法被触发。

这发生在types为UIButtonTypeDetailDisclosure的button上,但是它似乎没有发生UIButtonTypeCustombutton。 当我没有配件视图时,点击标注时代理方法也不会被触发。 (当然,这种行为并不令人惊讶;令人惊讶的是,如果附件视图是详细披露button,那么无论您是按下button本身还是在标注的其他位置,都会触发这两个方法。)

我想摆脱标注中的button – 或者至less用一个显示我自己的图像而不是股票“我”图标的buttonreplace – 同时仍然允许用户点击标注的任何地方以触发我的操作。 这可能吗? 我没有看到一个MKMapViewDelegate方法对应于“标注挖掘”。

尝试在不更改UIButtonTypeDetailDisclosuretypes的情况下为button设置自定义图像。

 UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; [detailButton setImage:[UIImage imageNamed:@"icon"] forState:UIControlStateNormal]; 

对于iOS7及以上版本,此图像默认为着色。 如果您想保留原始图标,请使用以下内容

 [[UIImage imageNamed:@"icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] 

或者如果你想删除图标

 [detailButton setImage:[UIImage new] forState:UIControlStateNormal]; 

要在用户点击注解视图后点击标注button, UITapGestureRecognizerdidSelectAnnotationView添加UITapGestureRecognizer 。 通过这种方式,您可以在不需要附件视图的情况下轻敲标注。

然后,您可以从发件人处获取注释对象以进一步执行操作。

 - (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view { UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(calloutTapped:)]; [view addGestureRecognizer:tapGesture]; } -(void)calloutTapped:(UITapGestureRecognizer *) sender { NSLog(@"Callout was tapped"); MKAnnotationView *view = (MKAnnotationView*)sender.view; id <MKAnnotation> annotation = [view annotation]; if ([annotation isKindOfClass:[MKPointAnnotation class]]) { [self performSegueWithIdentifier:@"annotationDetailSegue" sender:annotation]; } } 

Dhanu A在Swift 3中的解决scheme :

 func mapView(mapView: MKMapView, didSelectAnnotationView view:MKAnnotationView) { let tapGesture = UITapGestureRecognizer(target:self, action:#selector(calloutTapped(sender:))) view.addGestureRecognizer(tapGesture) } func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView) { view.removeGestureRecognizer(view.gestureRecognizers!.first!) } func calloutTapped(sender:UITapGestureRecognizer) { let view = sender.view as! MKAnnotationView if let annotation = view.annotation as? MKPointAnnotation { performSegue(withIdentifier: "annotationDetailSegue", sender: annotation) } } 

如果你不需要点击指示,build议在创build时将一个UITapGestureRecognizer引入到标注中,并用适当的操作将你的处理对象(可能是控制器)添加为目标。

 - (void)mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { Park *parkAnnotation = (Park *)[view annotation]; switch ([control tag]) { case 0: // left button { NSURL *url = [NSURL URLWithString:parkAnnotation.link]; [[UIApplication sharedApplication] openURL:url]; } break; case 1: // right button { // build a maps url. This will launch the Maps app on the hardware, and the apple maps website in the simulator CLLocationCoordinate2D coordinate = self.locationManager.location.coordinate; NSString *url2 = [NSString stringWithFormat:@"http://maps.apple.com/maps?saddr=%f,%f&daddr=%f,%f",coordinate.latitude,coordinate.longitude,parkAnnotation.location.coordinate.latitude,parkAnnotation.location.coordinate.longitude]; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url2]]; } break; default: NSLog(@"Should not be here in calloutAccessoryControlTapped, tag=%ld!",(long)[control tag]); break; } }