4

Within following method of MKMapViewDelegate:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

    let pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "")
    pinAnnotationView.rightCalloutAccessoryView = UIButton(type: .DetailDisclosure)
    pinAnnotationView.canShowCallout = true

    return pinAnnotationView
}

If I do it like above, then a whole view is tappable:

enter image description here

otherwise:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

        let pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "")
        let accessoryView = UIButton(frame: CGRectMake(0, 0, 25, 25))
        accessoryView.setImage(UIImage(named: "icon-menu"), forState: .Normal)

        pinAnnotationView.rightCalloutAccessoryView = accessoryView
        pinAnnotationView.canShowCallout = false

        return pinAnnotationView
}

only right accessory view is tapped, why?

The question is. What to do to make tappable a whole MKPinAnnotationView not just its right disclosure?

Bartłomiej Semańczyk
  • 59,234
  • 49
  • 233
  • 358

1 Answers1

5

I am still searching on why that works for full callout view in the first code block but not in the second one.

And I found the answer for how to make the whole MKPinAnnotationView callout view tappable.

Basically we can achieve this in two methods.

1. using normal method.

Here I am using an image for the rightCalloutAccessoryView but there is small change while declaring the button as below.

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    let reuseIdentifier = "pin"
    var pin = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseIdentifier) as? MKPinAnnotationView
    if pin == nil {
        pin = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
        pin!.pinTintColor = UIColor.redColor()
        pin!.canShowCallout = true
        let button = UIButton(type: .DetailDisclosure)
        button.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
        button.setBackgroundImage(UIImage(named: "img.png"), forState: .Normal)
        pin!.rightCalloutAccessoryView = button
    } else {
        pin!.annotation = annotation
    }
    return pin
}

Here while declaring the Button I am specifying as DetailDisclosure type.

2. Second method is using the UITapGestureRecognizer

Here I am implementing two callout delegate methods as follows.

//called when select an annotation
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapped))
    view.addGestureRecognizer(tapGestureRecognizer)
}
//Called when deselects the annotation
func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView) {
    view.removeGestureRecognizer(view.gestureRecognizers!.first!)
}
func tapped(sender: UITapGestureRecognizer) {
    if let view = sender.view as? MKAnnotationView {
        performSegueWithIdentifier("info", sender: view)
        //do yours
    }
}
Naveen Kumar H S
  • 1,304
  • 16
  • 30