I am attempting to set up a scrollable list in my React Native iOS app that also enables left and right swiping. For this list, I am using ScrollView with the PanResponder
utility in React Native for gesture handling. Currently, I am able to swipe list items left and right. However, after swiping at least one list item either left or right, I cannot seem to immediately scroll through the list. It appears that the list items remain sensitive to the scroll up/down gesture. After a few up/down gestures, the scroll finally responds. To fix this, I tried adding handleScrollBegin
and handleScrollEnd
functions to change the state of swipeEnabled
depending on the state of onScrollBeginDrag
and onScrollEndDrag
in the ScrollView. However, this also didn't resolve the issue. Any idea how I can fix my SwipeList so as to enable scrolling after swiping? See my code below:
const SwipeList = ({ data }) => {
const [swipeEnabled, setSwipeEnabled] = useState(true);
const SwipeRow = ({ item, swipeEnabled }) => {
const swipeX = new Animated.Value(0);
const panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => swipeEnabled,
onMoveShouldSetPanResponder: () => swipeEnabled,
onPanResponderMove: (event, gestureState) => {
swipeX.setValue(gestureState.dx);
},
onPanResponderRelease: async (event, gestureState) => {
// Handle swiping right or left here
if (gestureState.dx > 75) {
// Swiped right
Animated.timing(swipeX, {
toValue: 200,
duration: 200,
useNativeDriver: false,
}).start(() => {
console.log('Swiped right'); // Handle swiping right
});
}
else if (gestureState.dx < -75) {
// Swiped left
Animated.timing(swipeX, {
toValue: 200,
duration: 200,
useNativeDriver: false,
}).start(() => {
console.log('Swiped left'); // Handle swiping left
});
}
else {
// Reset position
Animated.timing(swipeX, {
toValue: 0,
duration: 200,
useNativeDriver: false,
}).start();
}
return false; // Release the touch event to the scroll
},
});
const animatedStyle = {
transform: [{ translateX: swipeX }],
};
return (
<Animated.View style={[styles.listItem, animatedStyle]}>
<RectButton style={{ flex: 1 }} {...panResponder.panHandlers}>
<View style={{ paddingHorizontal: 10, paddingVertical: 20 }}>
<Text>{item.name}</Text>
</View>
</RectButton>
</Animated.View>
);
};
const handleScrollBegin = () => {
setSwipeEnabled(false);
};
const handleScrollEnd = () => {
setSwipeEnabled(true);
};
return (
<ScrollView
onScrollBeginDrag={handleScrollBegin}
onScrollEndDrag={handleScrollEnd}
>
{data.map(item => (
<SwipeRow key={item.id} item={item} swipeEnabled={swipeEnabled} />
))}
</ScrollView>
);
};