Skip to content
This repository was archived by the owner on Aug 8, 2023. It is now read-only.

Expose MGLMapView’s internal gesture recognizers publicly #2278

Closed
maciekish opened this issue Sep 8, 2015 · 10 comments
Closed

Expose MGLMapView’s internal gesture recognizers publicly #2278

maciekish opened this issue Sep 8, 2015 · 10 comments
Labels
iOS Mapbox Maps SDK for iOS

Comments

@maciekish
Copy link
Contributor

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.

@maciekish
Copy link
Contributor Author

Here goes nothing: #2280

@friedbunny friedbunny added the iOS Mapbox Maps SDK for iOS label Sep 9, 2015
@1ec5
Copy link
Contributor

1ec5 commented Oct 21, 2015

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.

@f2m2rd
Copy link

f2m2rd commented May 4, 2016

+1

1 similar comment
@kristophM
Copy link

+1

@1ec5 1ec5 mentioned this issue Aug 22, 2016
@1ec5 1ec5 changed the title Tap and long press delegate methods Expose MGLMapView’s internal gesture recognizers publicly Aug 22, 2016
@1ec5
Copy link
Contributor

1ec5 commented Aug 22, 2016

As explained in #2280 (comment), 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.

@1ec5
Copy link
Contributor

1ec5 commented Nov 26, 2016

By the way, here’s a workaround:

mapView.gestureRecognizers.filter { $0 is UITapGestureRecognizer }.first

@1ec5
Copy link
Contributor

1ec5 commented Nov 30, 2016

#7194 would make the built-in tap gesture recognizer fail whenever it ends up doing nothing, so that another gesture recognizer in application space can take over.

@1ec5
Copy link
Contributor

1ec5 commented Dec 1, 2016

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?

@nitrag
Copy link
Contributor

nitrag commented Jan 18, 2017

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)} }

@1ec5
Copy link
Contributor

1ec5 commented Jan 19, 2017

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.)

nitrag added a commit to nitrag/mapbox-gl-native that referenced this issue Jan 23, 2017
Adding Gesture info as discussed: mapbox#2278 (comment)

Not sure if using codeblocks is kosher.
1ec5 pushed a commit that referenced this issue Jan 23, 2017
* Expand on Gesture Implementation

Adding Gesture info as discussed: #2278 (comment)

Not sure if using codeblocks is kosher.

* Update styling and verbiage

* More updates

* [ios] -requireGestureRecognizerToFail: seems to be enough

* [macos] Added corresponding macOS documentation
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
iOS Mapbox Maps SDK for iOS
Projects
None yet
Development

No branches or pull requests

7 participants