1

I made a swipeable row inside my FlatList using PanGestureHandler and reanimated 2. However, my swiping conflicts with the TouchableWithoutFeedback/TouchableOpacity I have when you press on that row.. Is there anyway to disable the onPress while the swiping is happening? I tried doing it like this by using runOnJS(onStart)(), which disables the TouchableOpacity in the parent component, but have been unsuccessful. I think it's because if the onPress was registered before it was disabled, it will still trigger on release.

const Swipeable = props => {
  const { onSwipe, children, onStart, onEnd } = props
  const translateX = useSharedValue(0)
  const scaledButtonX = useSharedValue(scale(50))
  const translateXButton = useDerivedValue(() => {
    return translateX.value + scaledButtonX.value
  })
  const offsetX = useSharedValue(0);
  const onGestureEvent = useAnimatedGestureHandler({
    onStart: (_, ctx) => {
      ctx.x = translateX.value
      runOnJS(onStart)() // this disables the onPress in the parent component
    },
    onActive: (event, ctx) => {
      translateX.value = ctx.x + clamp(event.translationX, -9999, -ctx.x)
    },
    onEnd: (event, ctx) => {
      const to = snapPoint(translateX.value, event.velocityX, snapPoints)
      translateX.value = withTiming(to, {
        easing: Easing.linear,
        duration: 200
      })
      ctx.x = translateX.value
      runOnJS(onEnd)() // this enables it back
    }
  })

  const style = useAnimatedStyle(() => {
    return {
      transform: [{ translateX: translateX.value }],
    }
  })

  const buttonStyle = useAnimatedStyle(() => {
    return {
      position: 'absolute',
      top: 0,
      bottom: 0,
      left: 0,
      right: 0,
      flexDirection: "row",
      justifyContent: "flex-end",
      alignItems: "center",
      overflow: "hidden",
      transform: [{ translateX: translateXButton.value }]
    }
  })

  const onDelete = () => {
    translateX.value = withSequence(withTiming(-(width + scale(50))), withTiming(0, {
      duration: 500
    }, () => console.log('done2')))
    // translateX.value = withTiming(0, {}, () => console.log('done'))
    onSwipe()
  }

  return (
    <View style={{ position: 'relative' }}>
      <Animated.View style={buttonStyle}>
        <TouchableOpacity style={styles.deleteButtonContainer} onPress={onDelete}>
          <View style={styles.deleteButton}>
            <Icon name='x' size={scale(20)} color={Colors.darkPurple} />
          </View>
        </TouchableOpacity>
      </Animated.View>
      <PanGestureHandler failOffsetY={[-5, 5]} activeOffsetX={[-5, 5]} onGestureEvent={onGestureEvent}>
        <Animated.View style={style}>
          {children}
        </Animated.View>
      </PanGestureHandler>
    </View>
  )
}
Timur Ridjanovic
  • 1,002
  • 1
  • 12
  • 18
  • I'm actually almost there.. is there a way to access a modified prop or state from useAnimatedGestureHandler? I can't seem to access the modified state from inside the onStart, onActive, onEnd handlers.. I can only have the initial prop or state value.. – Timur Ridjanovic Jul 16 '21 at 04:00

0 Answers0