react-native-gesture-handler
react-native-gesture-handler copied to clipboard
`Gesture.Exclusive` functionality differs on iOS vs Android
Description
I'm copying examples from the docs and came across the double tap example. It seems to work fine on Android, but not on iOS.
Platforms
- [ ] iOS (not working)
- [x] Android (working)
Steps To Reproduce
- I made an
mvce
example repo here. It's using expo, justyarn
andyarn start
and run iOS/Android as desired. You'll see on iOS the single is always logged (and the others never fire), but on Android they fire as expected.
Expected behavior
I would expect Gesture.Exclusive
to function as it does on Android, prioritizing the order of the gestures passed in. I've tried using onStart
instead of onEnd
as found in the docs here (which are slightly out of date with the maxDurationMs
prop) and ended up going with this example found here
Actual behavior
On iOS, it seems like the single tap inevitably steals the gesture and always logs itself. If I comment out the single tap and run it as just double/triple, only double tap works (even though, again, I'd expect triple to take priority)
Snack or minimal code example
Example repo here
Package versions
- React: 17.0.1
- React Native: 0.64.3 (generic expo init using 44.0.0)
- React Native Gesture Handler: ~2.1.0
- React Native Reanimated: ~2.3.1
Hi! This seems to be related to https://github.com/software-mansion/react-native-gesture-handler/issues/1804 as I was able to reproduce it only in managed workflow.
Thanks @j-piasecki, you're right. I ejected from expo and both platforms work fine.
Hi, any updates with this issue?
Just keeping this alive—I can't comment on whether this exists with the bare workflow but at the moment it seems Exclusive
is not functional on iOS, with latest dependencies.
Anyone aware of any other way to implement single and double tap gestures on the same View in this context?
@samtgarson you can use Gesture.Race
const tapGesture = Gesture.Tap().onEnd((event) => {
// your single tab code
})
const doubleTab = Gesture.Tap().numberOfTaps(2).onEnd(() => {
// your double tab code
})
const singleAndDoubleTab = Gesture.Race(tapGesture, doubleTab)
@slytter this always calls the single tap callback in my test.
I would have thought that the single tap would always register before the double tap, so Race would always end up calling the single tap callback anyway?