Combining Pan Gesture and Swipeable creates unexpected behavior
Athe81 opened this issue · 4 comments
Description
I have a GestureDetector with a pan gesture wraped around a Swipeable element. After wrapping the GestureDetector around the Swipeable element, the Swipeable Element does not work as expected. Before it opened or closed after releasing the finger. Now it stucks in the position.
Steps to reproduce
- Create a Swipeable element
- Wrap it with a GestureDetector (gesture pan)
- Test it
Snack or a link to a repository
https://snack.expo.dev/@bigbart/bugreport-swipeable-list
Gesture Handler version
2.14.0
React Native version
0.73.6
Platforms
iOS
JavaScript runtime
Hermes
Workflow
Expo managed workflow
Architecture
None
Build type
None
Device
None
Device model
No response
Acknowledgements
Yes
Hi @m-bert!
Why do you want to wrap
Swipeable
withGestureDetector
?Swipeables
already have gesture handlers under the hood.
I want to give a haptic feedback to the user, if the Swipeable
item is swiped more than a threshold. This is to signalize the user, that the action behind, will be executed if he releases his finger.
I don't know how to do this without GestureDetector
.
I see. In that case you can try something like this:
const Item = ({ id, title }) => {
const windowWidth = Dimensions.get('window').width;
const threshold = windowWidth / 3;
const hasReachedThreshold = useSharedValue(false);
const panRef = useRef();
const panGesture = Gesture.Pan()
.onUpdate((e) => {
hasReachedThreshold.value = Math.abs(e.translationX) >= threshold;
console.log(hasReachedThreshold.value);
})
.withRef(panRef);
const renderLeftActions = (progress, dragX) => {
return <View style={styles.left} />;
};
const renderRightActions = (progress, dragX) => {
return <View style={styles.right} />;
};
return (
<GestureDetector gesture={panGesture}>
<View>
<Swipeable
key={id}
simultaneousHandlers={panRef}
renderLeftActions={renderLeftActions}
renderRightActions={renderRightActions}
leftThreshold={threshold}
rightThreshold={threshold}>
<View style={styles.item}>
<Text style={styles.text}>{title}</Text>
</View>
</Swipeable>
</View>
</GestureDetector>
);
};
I've made a few changes in your code:
- I've wrapped
Swipeable
withView
so thatGestureDetector
won't be using the same view as swipeable component - I've added
withRef
so you can markPan
assimultaneous
with gesture handlers insideSwipeable
With these changes I was able to achieve what I believe is what you're trying to do. Let me know if it helps!
It helped a lot. It works perfect now. Thanks a lot.
I didn't know the simultaneousHandlers