Búsqueda de sitios web

javascript - React Native: ¿Cómo desactivar PanResponder temporalmente?


A continuación se muestra el fragmento para crear una instancia del panResponder:

  constructor( props ) {
    super( props );

    this.position = new Animated.ValueXY();

    this.panResponder = PanResponder.create( {
      onStartShouldSetPanResponder: ( ) => true,
      onPanResponderMove: ( event, gesture ) => {
        this.position.setValue( { x: 0, y: gesture.dy } );
      },
      onPanResponderRelease: ( event, gesture ) => {
        if ( gesture.dy > SWIPE_THRESHOLD ) {
          this.forceSwipe( 'up' );
        } else if ( gesture.dy < -SWIPE_THRESHOLD ) {
          this.forceSwipe( 'down' );
        } else {
          this.resetPosition();
        }
      },
      onMoveShouldSetPanResponderCapture: ( evt, gestureState ) =>
      gestureState.dx !== 0 && gestureState.dy !== 0,
    } );
  }

  getCardStyle() {
    return {
      ...this.position.getLayout(),
    };
  }

A continuación se muestra el fragmento de código de mi componente:

<Animated.View
   key={ item.id }
   style={ [ this.getCardStyle(), styles.cardStyle ] }
   { ...this.panResponder.panHandlers }
>
  <Card
    shouldPanRespond={ this.shouldPanRespond }
     item={ item }
  />
</Animated.View>

Fragmento de código para el componente de tarjeta:

  <TouchableOpacity
    activeOpacity={ 1 }
    style={ cardStyle }
    onPress={ this.onPress }
  >
    <ScrollView contentContainerStyle={ cardStyle }>
      <Image
        resizeMode="cover"
        style={ imageStyle }
        source={ { uri: img_url } }
      />

      <View style={ titleWrapStyle }>
        <Text style={ textStyle }>{ title }</Text>
      </View>
    </ScrollView>
  </TouchableOpacity>

Estoy construyendo tarjetas que están posicionadas absolutamente una detrás de otra. Estas tarjetas luego pueden deslizarse hacia arriba o hacia abajo usando el panResponder. Pero, al tocar la pantalla se supone que debo mostrar una página de detalles en la misma pantalla.

Ahora, puedo detectar el toque, pero cada vez que el usuario toque/haga clic, quiero deshabilitar el panResponder para que la tarjeta no se pueda deslizar y el usuario pueda desplazarse por el contenido. Una vez que el usuario llegue al final del desplazamiento, quiero volver a habilitar el deslizamiento, es decir, quiero habilitar el paneo.

Sé que onStartShouldSetResponder:() => false desactiva panResponder, pero ¿cómo lo desactivamos después de que se crea una instancia? No pude encontrar mucha información al respecto en otros lugares.

Respuesta #1

Para alguien que estará buscando cómo desactivar temporalmente PanResponder, a continuación está mi solución.

Como @RaHuL - House Javascript notó, la otra respuesta realmente no resuelve el problema porque establecer onStartShouldSetResponder en un valor que corresponde a algún valor de estado que podría cambiar de verdadero a falso no afectará a PanResponder (al menos parece ser así) si se creó con true.

Resolví un problema similar cambiando la función onPanResponderMove. Tengo un valor dentro del estado: panResponderEnabled y mi función se ve así:

 onPanResponderMove: ( event, gesture ) => {
    if(this.state.panResponderEnabled){
       this.position.setValue( { x: 0, y: gesture.dy } ); 
    }
}

Cuando no quiero leer los cambios de PanResponder, simplemente configuro panResponderEnabled en falso.

Respuesta #2

Si quieres una solución de fuerza bruta realmente simple, usa la propiedad pointerEvents en la vista animada.

pointerEvents={stopPan ? 'none' : 'auto'}

Esto detendrá todos los eventos táctiles en la vista y en todas las de abajo mientras stopPan sea verdadero.