Repository navigation
requireExternalGestureToFail is not able to block a ScrollView #3266
Copy link
Copy link
Open
Labels
Platform: iOSThis issue is specific to iOSThis issue is specific to iOSRepro providedA reproduction with a snack or repo is providedA reproduction with a snack or repo is provided
Description
Description
According to the docs, requireExternalGestureToFail is like the inverse of blocksExternalGesture.
However, I can't actually get requireExternalGestureToFail to do anything useful with a native gesture.
In particular, I want to block ScrollView if my Pan is being recognized.
The docs lead me to believe that this code would work:
import {View} from 'react-native'
import {
Gesture,
GestureDetector,
GestureHandlerRootView,
ScrollView,
} from 'react-native-gesture-handler'
export default function App() {
const pan = Gesture.Pan()
.onBegin(() => {
'worklet'
console.log('begin')
})
.onUpdate(() => {
'worklet'
console.log('update')
})
.onEnd(() => {
'worklet'
console.log('end')
})
.onFinalize(() => {
'worklet'
console.log('finalize')
})
return (
<GestureHandlerRootView>
<GestureDetector gesture={pan}>
<View style={{flex: 1, backgroundColor: 'blue'}}>
<ScrollViewExample pan={pan} />
</View>
</GestureDetector>
</GestureHandlerRootView>
)
}
function ScrollViewExample({pan}) {
const native = Gesture.Native().requireExternalGestureToFail(pan)
return (
<GestureDetector gesture={native}>
<ScrollView
horizontal
pagingEnabled
style={{
flex: 1,
backgroundColor: 'yellow',
}}>
<View
style={{
width: 200,
height: '100%',
backgroundColor: 'green',
}}
/>
<View
style={{
width: 200,
height: '100%',
backgroundColor: 'purple',
}}
/>
</ScrollView>
</GestureDetector>
)
}But it doesn't do anything. The ScrollView is still in control of the gesture.
Steps to reproduce
- Drag the ScrollView
- The ScrollView gets dragged, but it should have been blocked by the Pan
this_shouldnt_be_dragggable.mov
Snack or a link to a repository
https://snack.expo.dev/k1-MTyYfvD3wQNk3sr_je
Gesture Handler version
2.20.2
React Native version
0.76.3
Platforms
iOS
JavaScript runtime
Hermes
Workflow
Expo bare workflow
Architecture
Paper (Old Architecture)
Build type
Debug mode
Device
Real device
Device model
No response
Acknowledgements
Yes
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Platform: iOSThis issue is specific to iOSThis issue is specific to iOSRepro providedA reproduction with a snack or repo is providedA reproduction with a snack or repo is provided
Activity
gaearon commentedon Dec 7, 2024
OMG. I accidentally imported
ScrollViewfrom RNGH (due to my IDE) and that's why it did not work. If I change theScrollViewimport to be fromreact-native, it works. Not sure how to feel about it but this definitely simplifies things.j-piasecki commentedon Dec 9, 2024
That's the correct thing to do if you're using the API from RNGH2 (
<GestureDetector />).ScrollViewexported from RNGH is a convenience wrapper that automatically wraps the ScrollView withNativeViewGestureHandler(the old API). It's kept for backwards compatibility with RNGH 1 so updates would be less painful. We are in the process of cleaning up the package for the next major and dealing with the components mess is high on the TODO list.Anyway, it didn't work with
ScrollViewfrom RNGH because there were two native gestures attached to it - the one you created and the one from the wrapper. The one from the wrapper was deeper in the tree, so it got priority for event handling, and the relations you defined didn't get a chance to work.Generally, if you want to use
Gesture.Nativeon a component you shouldn't do it on components exported from RNGH as those come with it preapplied.I'll see what can be done about the docs, hopefully, we'll have them updated by the time the next major releases.
gaearon commentedon Dec 9, 2024
Ohh ok that makes sense (and yeah, not very obvious). Could
GestureHandlerbe made to warn if its direct child is an RNGH back compat component?It would be nice to mark those old top-level as
@deprecatedin TS. I did not actually realize what they were for and that they were related to an older API.gaearon commentedon Dec 9, 2024
My two cents is that
requireExternalGestureToFaildocs need to show how to block native views. It is documented neither inrequireExternalGestureToFaildocs nor inGesture.Native()docs. It is not obvious that they work together.j-piasecki commentedon Dec 10, 2024
That should be doable, I'll need to double check whether it's detectable without any false positives (they use the same native handler under the hood).
We are looking into updating them not to use the old API but we haven't reached any conclusions yet.