Hi,
In the old MapBox there were two delegate methods that are missing in MapBox-gl. Namely - (void)singleTapOnMap:(RMMapView *)map at:(CGPoint)point and - (void)longPressOnMap:(RMMapView *)map at:(CGPoint)point. We used the first to cancel overlays and the second to drop a pin for geocoding.
Is there any plan for adding these to MapBox-gl please? I can see there are already single and long tap recognizers in MGLMapView.mm but there is no delegate. If you don't have time, will you perhaps take a PR for this?
We can't do this in our app code because for example we don't want the singleTapOnMap method to fire when the user taps an annotation, only when touching the map itself.
Here goes nothing: #2280
we don't want the singleTapOnMap method to fire when the user taps an annotation, only when touching the map itself.
That’s a reasonable consideration. Perhaps built-in gesture recognizers should be exposed publicly, so you can implement your own gesture recognizer and have it depend on the built-in one failing.
+1
+1
As explained in https://github.com/mapbox/mapbox-gl-native/pull/2280#issuecomment-150007468, we should expose the gesture recognizers that MGLMapView uses internally – or at least the tap gesture recognizer – as read-only public properties. That would allow client code to implement -gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: more intelligently.
To be clear, it is already possible to install your own tap and long press gesture recognizers, but by default they always block the tap gesture recognizer built into MGLMapView. It’s even possible already to pass through certain gestures by implementing -gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:. But to have one gesture recognizer handle annotation selection and the other handle all other taps, you probably would need the built-in recognizer to be exposed publicly.
By the way, here’s a workaround:
mapView.gestureRecognizers.filter { $0 is UITapGestureRecognizer }.first
Now that #7246 has landed with a fix for #7194 (thanks @JesseCrocker!), you can add a tap gesture recognizer to MGLMapView as a fallback when MGLMapView’s built-in gesture recognizers have nothing to do:
for (UIGestureRecognizer *gestureRecognizer in self.mapView.gestureRecognizers) {
[fallbackTapGestureRecognizer requireGestureRecognizerToFail:gestureRecognizer];
}
for gestureRecognizer in mapView.gestureRecognizers {
fallbackTapGestureRecognizer.requireGestureRecognizerToFail = gestureRecognizer
}
Or, if you want your tap gesture recognizer to take precedence over built-in gesture recognizers other than the tap gesture recognizer used for selecting annotations:
for (UIGestureRecognizer *gestureRecognizer in self.mapView.gestureRecognizers) {
if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
[fallbackTapGestureRecognizer requireGestureRecognizerToFail:gestureRecognizer];
}
}
for gestureRecognizer in mapView.gestureRecognizers {
if gestureRecognizer is UITapGestureRecognizer {
fallbackTapGestureRecognizer.requireGestureRecognizerToFail = gestureRecognizer
}
}
This fix will be present in iOS SDK v3.4.0 beta 5. Are there any remaining unmet use cases where we would need to expose the tap gesture recognizer explicitly?
Full implementation for Swift 3.
@1ec5, Let me know if this is good, I'll submit a PR to add this to the docs under -mapView:didSelectAnnotation: if so. I got caught up on this for a while, then figured out I wasn't doing anything wrong it was just being overwritten.
let mapTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(mapTap))
if let gestures = self.mapView.gestureRecognizers {
for gestureRecognizer in gestures {
if gestureRecognizer is UITapGestureRecognizer {
mapTapGestureRecognizer.require(toFail: gestureRecognizer)
mapView.addGestureRecognizer(mapTapGestureRecognizer)
}
}
}
OR:
let mapTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(mapTap))
self.mapView.gestureRecognizers?.forEach { if($0 is UITapGestureRecognizer){mapTapGestureRecognizer.require(toFail: $0)} }
Sure, a PR would be welcome! (One piece of feedback right off the bat: it looks like the first version could add the same gesture recognizer multiple times.)
Most helpful comment
As explained in https://github.com/mapbox/mapbox-gl-native/pull/2280#issuecomment-150007468, we should expose the gesture recognizers that MGLMapView uses internally – or at least the tap gesture recognizer – as read-only public properties. That would allow client code to implement
-gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:more intelligently.To be clear, it is already possible to install your own tap and long press gesture recognizers, but by default they always block the tap gesture recognizer built into MGLMapView. It’s even possible already to pass through certain gestures by implementing
-gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:. But to have one gesture recognizer handle annotation selection and the other handle all other taps, you probably would need the built-in recognizer to be exposed publicly.