Is it possible to receive events for a handler, e.g. PanGestureHandler, and a ScrollView at the same time? I鈥檓 finding that a ScrollView fully consumes a touch event, even with simultaneousHandlers set, so that a gesture handler that contains the ScrollView never receives the touch as long as the ScrollView is enabled.
Answer: Wrapping the ScrollView in a NativeViewGestureHandler, with both gesture handlers pointing to each other's refs in the simultaneousHandlers prop, works perfectly.
There is no documentation about NativeViewGestureHandler on official site, but the only mention of it says that you can use FlatList from react-native-gesture-handler with simultaneousHandlers instead of wrapping it inside NativeViewGestureHandler.
But you cannot
import { FlatList, PanGestureHandler } from 'react-native-gesture-handler';
// This handler will only fire if FlatList does not detect scroll
<PanGestureHandler
ref={panRef}
simultaneousHandlers={listRef}
>
<FlatList
ref={listRef}
simultaneousHandlers={panRef}
...
/>
</PanGestureHandler>
So you still should use FlatListONLY from react-native and wrap it in NativeViewGestureHandler:
import { FlatList } from 'react-native';
import { PanGestureHandler, NativeViewGestureHandler } from 'react-native-gesture-handler';
<PanGestureHandler
ref={panRef}
simultaneousHandlers={listRef}
>
<NativeViewGestureHandler
ref={listRef}
simultaneousHandlers={panRef}
/>
<FlatList/>
</NativeViewGestureHandler>
</PanGestureHandler>
There is no FlatList in current documentation from this repo. But it was added in this PR. IDK
@damikdk thanks, your research helped me.
I'd add one caveat though. For anybody planning to use an Animated.event for a PanGestureHandler onHandlerStateChange for example. In that case one must wrap a NativeViewGestureHandler inside an Animated.View. Otherwise the app will be failing with an error Nesting touch handlers with native animated driver is not supported yet.
Credits:聽#71
Just in case, here's a full example:
`js
const ScrollContainer = styled(Animated.ScrollView).attrs({
scrollEventThrottle: 16,
contentContainerStyle: { paddingBottom: 40 },
})
const Container = React.forwardRef((props, ref) => {
const handlerRef = useRef()
const { onScroll, onHandlerStateChange, children } = props
return <Animated.View>
<NativeViewGestureHandler ref={handlerRef}>
<ScrollContainer ref={ref} {...{onScroll}}>
{children}
</ScrollContainer>
</NativeViewGestureHandler>
</Animated.View>
})
I use [email protected]. It seems neither of the suggested solutions work. I've tried all kinds of simultaneousHandlers combinations, ScrollViews from react-native-gesture-handler and from react-native etc.
Here:
class List extends PureComponent<Props> {
panRef
listRef
render () {
const { children } = this.props
return (
<View style={styles.container}>
<PanGestureHandler
onGestureEvent={() => console.log('onGestureEvent')}
ref={ref => (this.panRef = ref)}
simultaneousHandlers={this.listRef}
>
<NativeViewGestureHandler
ref={ref => (this.listRef = ref)}
simultaneousHandlers={this.panRef}
>
<ScrollView
// scrollEnabled={false}
style={styles.foodListScroll}
>
{children}
</ScrollView>
</NativeViewGestureHandler>
</PanGestureHandler>
</View>
)
}
}
PanGestureHandler fires onGestureEvent only when the ScrollView is disabled with scrollEnabled={false}.
@damikdk @yzalvov could you take a look?
Most helpful comment
There is no documentation about
NativeViewGestureHandleron official site, but the only mention of it says that you can useFlatListfromreact-native-gesture-handlerwithsimultaneousHandlersinstead of wrapping it insideNativeViewGestureHandler.But you cannot
So you still should use
FlatListONLY fromreact-nativeand wrap it inNativeViewGestureHandler:There is no
FlatListin current documentation from this repo. But it was added in this PR. IDK