Pan gesture inside a ScrollView blocks scrolling
See original GitHub issueDescription
I have a use case where I have a draggable element which I implement using Pan Gesture. This element is being rendered inside a ScrollView and block scrolling when attempting to scroll in the pan area (of the element)
Assuming that the pan conflicts with the scroll I tried to approach it differently and added a LongPress gesture that once started enables the panning, so as long as the user didn’t long press the element, the pan gesture should not block the scrolling.
I pretty much implemented this example with minor changes https://docs.swmansion.com/react-native-gesture-handler/docs/gesture-composition#race
This is the LongPress gesture
const longPressGesture = Gesture.LongPress()
.onStart(() => {
isDragging.value = true;
});
This is the Pan gesture
const dragGesture = Gesture.Pan()
.onStart(() => {...})
.onUpdate(event => {....})
.onFinalize(() => {
isDragging.value = false;
})
.simultaneousWithExternalGesture(longPressGesture);
And finally
const composedGesture = Gesture.Race(dragGesture, longPressGesture);
<GestureDetector gesture={composedGesture}>
<View reanimated>{props.children}</View>
</GestureDetector>
I was thinking on invoking dragGesture.enabled(false/true)
to enable/disable the panning, but TBH, I’m not sure where to call it.
Any ideas how to approach this?
Platforms
- iOS
- Android
- Web
Screenshots
Steps To Reproduce
- Either use the code mention in the description in order to reproduce the full problem, or use the one from this guide and wrap the component with a ScrollView
- The code snippet below is more focused on the issue with a ScrollView that wraps a pan gesture component and how it blocks the scrolling
Expected behavior
Actual behavior
Snack or minimal code example
This is a small code snippet that demonstrate the general issue of pan/scroll not working together. Scrolling on the DragComponent area will not work, only below it will work
const DragComponent = props => {
const gesture = Gesture.Pan();
return (
<GestureDetector gesture={gesture}>
<View reanimated>{props.children}</View>
</GestureDetector>
);
};
const Main = () => {
return (
<ScrollView>
<DragComponent>
<View style={{width: '100%', height: 400, backgroundColor: 'red'}}/>
</DragComponent>
</ScrollView>
);
}
Package versions
- React: 17.0.2
- React Native: 0.66.4
- React Native Gesture Handler: 2.3.0
- React Native Reanimated: 2.4.1
Issue Analytics
- State:
- Created 2 years ago
- Comments:8 (4 by maintainers)
Top GitHub Comments
Hi! Gestures blocking scrolling when they are placed inside ScrollView is by design, otherwise you wouldn’t be able to use them. The idea of requiring
LongPress
beforePan
can activate is a good way to get around that, but unfortunately, you cannon accomplish this usingRace
andSimultaneous
modifiers. You can accomplish this using touch events:Amazing! Thank you! I ended up combining your suggestion with my implementation.
I wanted to avoid implementing a LongPress behavior so I did the following and it works great!