Mapkit with LongPressGestureRecognizer working intermittently

Viewed 92

I have a very simple setup, where I have a MapKit, and I'd like to be able to drop pin to it everytime the user do a long press on the map. It works ok for the first pin. But if the user tried another long press (on another location), then the gesture is not recognized. The third time will work, the fourth time doesnt work, etc (every odd attempt will get recognized).

I have a sample project that demonstrate this: https://github.com/alexwibowo/SimpleLocationMarker

Basically, my view controller looks like below:

class ViewController: UIViewController {

    @IBOutlet weak var mapView: MKMapView! {
        didSet{
            let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.addNewAnnotation(recognizer:)))
            gestureRecognizer.minimumPressDuration = 0.5
            mapView.addGestureRecognizer(gestureRecognizer)
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @objc func addNewAnnotation(recognizer: UILongPressGestureRecognizer){
        if (recognizer.state != .began) {
            return
        }

        let touchPoint = recognizer.location(in: mapView)
        let wayCoords = mapView.convert(touchPoint, toCoordinateFrom: mapView)

        let annotation = MKPointAnnotation()
        annotation.title = "New"
        annotation.coordinate = wayCoords
        mapView.addAnnotation(annotation)
    }
}

extension ViewController: MKMapViewDelegate {

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let identifier = "locationMarkerIdentifier"
        var view: MKPinAnnotationView

        if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
            as? MKPinAnnotationView {
            dequeuedView.annotation = annotation
            view = dequeuedView
        } else {
            view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            view.annotation = annotation
            view.canShowCallout = true
            view.isDraggable = true
            view.calloutOffset = CGPoint(x: -5, y: 5)
            view.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
        }
        return view
    }


}

I'm sure it is a very simple mistake I've done!

1 Answers

First, set its delegate to self.

@IBOutlet weak var mapView: MKMapView! {
    didSet{
        let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.addNewAnnotation(recognizer:)))
        gestureRecognizer.minimumPressDuration = 0.5
        mapView.addGestureRecognizer(gestureRecognizer)
        gestureRecognizer.delegate = self
    }
}

Second,

extension ViewController : UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}
Related