Detect Tap on CalloutBubble in MKAnnotationView

三世轮回 提交于 2019-11-28 07:21:42

Could you add a gesture recognizer when you're initializing the MKAnnotationView?

Here's the code for inside dequeueReusableAnnotationViewWithIdentifier:

UITapGestureRecognizer *tapGesture = 
        [[UITapGestureRecognizer alloc] initWithTarget:self 
                                        action:@selector(calloutTapped:)];
[theAnnotationView addGestureRecognizer:tapGesture];
[tapGesture release];

The method for the gesture recognizer:

-(void) calloutTapped:(id) sender { 
    // code to  display whatever is required next.

    // To get the annotation associated with the callout that caused this event:
    // id<MKAnnotation> annotation = ((MKAnnotationView*)sender.view).annotation;
}

Here's the swift version of Dhanu's answer, including getting data from the item selected to pass to the next view controller:

func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
    let gesture = UITapGestureRecognizer(target: self, action: #selector(MyMapViewController.calloutTapped(_:)))
    view.addGestureRecognizer(gesture)
}

func calloutTapped(sender:UITapGestureRecognizer) {
    guard let annotation = (sender.view as? MKAnnotationView)?.annotation as? MyAnnotation else { return }

    selectedLocation = annotation.myData
    performSegueWithIdentifier("mySegueIdentifier", sender: self)
}

To tap the callout button after the user has clicked on the Annotation view, add a UITapGestureRecognizer in didSelectAnnotationView. This way you can implement tap on the callout without needing the accessory views.

You can then get the annotation object back from the sender for further action.

- (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];
    }
}

Try to set custom image for button without changing UIButtonTypeDetailDisclosure type.

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

Swift 3, using On. You need to handle rightCalloutAccessoryView

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
  switch annotation {
  case let annotation as Annotation:
    let view: AnnotationView = mapView.dequeue(annotation: annotation)
    view.canShowCallout = true
    let button = UIButton(type: .detailDisclosure)
    button.on.tap { [weak self] in
      self?.handleTap(annotation: annotation)
    }
    view.rightCalloutAccessoryView = button
    return view
  default:
    return nil
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!