Detect on calloutAccessoryControlTapped only the tap on rightCalloutAccessoryView
Asked Answered
U

2

14

My calloutAccessoryControlTapped is also called when I just tap on annotation view and this behavior it's right. But how can I detect if the user has tapped on the right accessory view (in my case a detail disclosure button) and not just in the view?

I added a simple check but it doesn't work.

import UIKit
import MapKit

extension MapVC: MKMapViewDelegate, CLLocationManagerDelegate
{    
    func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl)
    {
        if control == view.rightCalloutAccessoryView
        {
            ... // enter here even if I tapped on the view annotation and not on button
        }
    }

}
Under answered 3/5, 2016 at 17:9 Comment(0)
B
5

To achieve it you would need to add target for the right accessory view. You can achieve it by setting button to rightCalloutAccessoryView as shown in the code snippet.

class MapViewController: UIViewController, MKMapViewDelegate {

    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
        if annotation is Annotation {
            let annotationView = AnnotationView(annotation: annotation, reuseIdentifier: "reuseIdentifier")
            let rightButton = UIButton(type: .DetailDisclosure)
            rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(_:)), forControlEvents: .TouchUpInside)
            annotationView.rightCalloutAccessoryView = rightButton
        }
        return nil
    }

    func didClickDetailDisclosure(button: UIButton) {
        // TODO: Perform action when was clicked on right callout accessory view.
    }
}

// Helper classes.
class Annotation: NSObject, MKAnnotation {
    var coordinate: CLLocationCoordinate2D
    var title: String?
    var subtitle: String?

    init(coordinate: CLLocationCoordinate2D, title: String, subtitle: String) {
        self.coordinate = coordinate
        self.title = title
        self.subtitle = subtitle
    }
}

class AnnotationView: MKAnnotationView {

}
Bonhomie answered 6/5, 2016 at 6:36 Comment(2)
Thanks for the answer. There's no way to use just the delegate method calloutAccessoryControlTapped?Under
I do not know another way. If you look into Apple source code they are doing it in the same way.Bonhomie
C
2
  1. Using UIView and UITapGestureRecognizer instead of UIControl

    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
      let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "reuseIdentifier")
      let gestureView = UIView(frame:CGRect(x: 0,y: 0,width: 20,height: 20))
      let gestureRecognizer = UITapGestureRecognizer()
      gestureRecognizer.addTarget(self, action:  #selector(MapViewController.didClickGestureRecognizer(_:)))
    
      gestureView.addGestureRecognizer(gestureRecognizer)
      gestureView.backgroundColor = UIColor.redColor()
      annotationView.rightCalloutAccessoryView = gestureView
      return annotationView
    }    
    
    func didClickGestureRecognizer(sender:UITapGestureRecognizer) -> Void {
      print("didClickGestureRecognizer")
    }
    

    When you click on rightCalloutAccessoryView, only didClickGestureRecognizer will be called,but your calloutAccessoryControlTapped cannot be invoked anyone.

2.If you have a UIControl as rightCalloutAccessoryView,you can tap directly on MKAnnotationView.Otherwise MKAnnotationView cannot be tapped.
Both your selector and calloutAccessoryControlTapped will be called when you tap rightCalloutAccessoryView or tap directly on MKAnnotationView

3.If you have a UIControl as leftCalloutAccessoryView,both your selector and calloutAccessoryControlTapped will be called when you tapped on it.

4.Since iOS 9,you can has a detailCalloutAccessoryView in your MKAnnotationView.Only your selector will be called when you tapped on it.

5.Also you can create your own custom MKAnnotationView,and change its behaviors.

Chassis answered 11/5, 2016 at 2:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.