The solution to this is to allow for simultaneous gestures. Simply set the long press gesture's delegate
and implement the following delegate method:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
That's it. The long press gesture on the map view will now work every time.
As a demonstration, create a new iOS project based on Swift and storyboard. Replace the provided ViewController.swift
implementation with the following:
import UIKit
import MapKit
class ViewController: UIViewController {
let mapView = MKMapView()
override func viewDidLoad() {
super.viewDidLoad()
mapView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(mapView)
NSLayoutConstraint.activate([
mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
mapView.topAnchor.constraint(equalTo: view.topAnchor),
mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
let lp = UILongPressGestureRecognizer(target: self, action: #selector(longPress))
lp.delegate = self
view.addGestureRecognizer(lp)
}
@objc func longPress(_ gesture: UILongPressGestureRecognizer) {
switch gesture.state {
case .began:
print("began")
case .ended:
print("ended")
case .changed:
print("changed")
case .cancelled:
print("cancelled")
default:
print("other")
}
}
}
extension ViewController: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
Do note that shouldRecognizeSimultaneouslyWith
will get called quite a few times. There seems to be at least 3 other gestures, including another long press gesture that expects two touches. So it's probably best not to setup your own long press gesture to require two touches.