1

In my iOS app I have an instance of an MKMapView and on single tap, I want to add a marker to the map. I've added a UITapGestureRecognizer and immediately noticed that it would fire even when a user double taps to zoom (or other interactions with the map).

I've implemented the UIGestureRecognizerDelegate method like this and this works, but makes the interaction very sluggish, because it obviously waits for the other gesture recognizers to fail.

    func gestureRecognizer(
        _ gestureRecognizer: UIGestureRecognizer,
        shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer
    ) -> Bool {
        guard gestureRecognizer == self.mapGestureRecognizer else {
            return false
        }

        return !(otherGestureRecognizer is UITapGestureRecognizer) && otherGestureRecognizer.state == .possible
    }

Is there any way to act quickly on a tap, without breaking the native gestures on the map view?

Erik Booij
  • 105
  • 10
  • Not sure there is a direct solution to this as the mapView can't know if your tap is part of another gesture until it's waited to check. My usual workaround for this is to use a long tap for adding markers to the map as this is a discrete event. – flanker Nov 24 '19 at 10:55
  • Thanks! That works for the biggest part, now there's only an issue where any first touch after the long press is missed or ignored. When I add this gesture recognizer and its handler to any other view, it works fine. On an `MKMapView` it blocks any next interaction, regardless of it's an actual new long press, or standard map interaction (like double tap, pan, pinch, etc). – Erik Booij Nov 24 '19 at 12:40
  • Never had that. Sure there's no other code left over from previous attempts? Also you're not doing anything heavy/synchronous on the main thread that's blocking responses? – flanker Nov 24 '19 at 12:45
  • No nothing, also tried it in a completely clean view controller with only an `MKMapView` added to it. – Erik Booij Nov 24 '19 at 15:04
  • I have created a minimal example that shows exactly this behavior. After a long press the next touch doesn't allow you to trigger it again, nor will it let you move the map, zoom, etc: https://pastebin.com/JLBQwt7w – Erik Booij Nov 24 '19 at 15:46
  • Also seems `MKMapView` specific. If I change the map view to be any other type of view, it works fine. – Erik Booij Nov 24 '19 at 15:55
  • Just tried it on a couple of my apps and not having the same behaviour. Does it do this only if the next touch is immediately after, or even if there's a slight gap between touches? – flanker Nov 24 '19 at 16:19
  • Both. Even if I wait for ten seconds, the problem still occurs. – Erik Booij Nov 24 '19 at 17:03
  • Weird! Would be worth raising another question specifically about that and putting in the MapView code. – flanker Nov 24 '19 at 17:10

1 Answers1

1

Not sure there is a direct solution to this as the mapView can't know if your tap is part of another gesture until it's waited to check. My usual workaround for this is to use a long tap for adding markers to the map as this is a discrete event

flanker
  • 3,840
  • 1
  • 12
  • 20