1

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>
  );
};

JS_is_awesome18
  • 1,587
  • 7
  • 23
  • 67

0 Answers0