Creating an annotation with longpress, suppresses tap handling for the map

I am creating annotations, by handling a longpress gesture.

It works just fine.

However, once the annotation is created, neither the annotation nor the map seem to recognize the tap gesture, and in order to get the callout, I have to tap twice on my annotation.

Is this normal? I have reproduced this 100% using samples, and it seems to happen only after a longpress gesture has been handled.

Is this a known issue? Does anyone know how to get around this?

Thank you!

Here is the code I am working with:

@IBOutlet weak var mapView: MKMapView!


// In ViewDidLoad

let uilpgr = UILongPressGestureRecognizer(target: self, action: #selector(createNewAnnotation))

uilpgr.minimumPressDuration = 0.25

mapView.addGestureRecognizer(uilpgr)


// The selector

@objc func createNewAnnotation(_ sender: UIGestureRecognizer) {

let touchPoint = sender.location(in: self.mapView)

let coordinates = mapView.convert(touchPoint, toCoordinateFrom: self.mapView)

let heldPoint = MKPointAnnotation()

heldPoint.coordinate = coordinates

if (sender.state == .began) {

heldPoint.title = "Set Point"

heldPoint.subtitle = String(format: "%.4f", coordinates.latitude) + "," + String(format: "%.4f", coordinates.longitude)

mapView.addAnnotation(heldPoint)

}

}


extension ViewController: MKMapViewDelegate {

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

if annotation is MKUserLocation {

return MKAnnotationView()

} else {

let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "annotationView") ?? MKAnnotationView()

annotationView.image = UIImage(named: "place icon")

annotationView.canShowCallout = true

return annotationView

}

}


I have tried many workarounds as this seems to be a bug...

Accepted Reply

After many days of searching, I finally found the solution. It might help someone at some point, because I could not find it anywhere in the documentation.

So, if you create an annotation with a long press, in order for the user to click on it to see the callout, your JUST need to cancel the long press, to make way for other gestures...

So here is the code in the selector:


// The selector

@objc func createNewAnnotation(_ sender: UIGestureRecognizer) {

let touchPoint = sender.location(in: self.mapView)

let coordinates = mapView.convert(touchPoint, toCoordinateFrom: self.mapView)

let heldPoint = MKPointAnnotation()

heldPoint.coordinate = coordinates

if (sender.state == .began) {

heldPoint.title = "Set Point"

heldPoint.subtitle = String(format: "%.4f", coordinates.latitude) + "," + String(format: "%.4f", coordinates.longitude)

mapView.addAnnotation(heldPoint)

}

// Cancel the long press to make way for the next gesture

sender.state = .cancelled

}


This little line made all the difference!

Replies

After many days of searching, I finally found the solution. It might help someone at some point, because I could not find it anywhere in the documentation.

So, if you create an annotation with a long press, in order for the user to click on it to see the callout, your JUST need to cancel the long press, to make way for other gestures...

So here is the code in the selector:


// The selector

@objc func createNewAnnotation(_ sender: UIGestureRecognizer) {

let touchPoint = sender.location(in: self.mapView)

let coordinates = mapView.convert(touchPoint, toCoordinateFrom: self.mapView)

let heldPoint = MKPointAnnotation()

heldPoint.coordinate = coordinates

if (sender.state == .began) {

heldPoint.title = "Set Point"

heldPoint.subtitle = String(format: "%.4f", coordinates.latitude) + "," + String(format: "%.4f", coordinates.longitude)

mapView.addAnnotation(heldPoint)

}

// Cancel the long press to make way for the next gesture

sender.state = .cancelled

}


This little line made all the difference!