Skip to content

RN Lez 17: Gesture Responder e PanResponder

Docs: Gesture Responder System, PanResponder

  • Capire il sistema di gesture di RN
  • Usare PanResponder per drag
  • Rilevare swipe direzioni

React Native ha un sistema che decide quale View risponde ai tocchi.

<View
onStartShouldSetResponder={() => true} // questo View cattura il tocco?
onMoveShouldSetResponder={() => true} // cattura movimento?
onResponderGrant={() => console.log('tocco iniziato')}
onResponderMove={(e) => console.log('muovendo...')}
onResponderRelease={() => console.log('rilasciato')}
onResponderTerminationRequest={() => false} // non cedere il controllo
style={{ width: 100, height: 100, backgroundColor: 'red' }}
/>

PanResponder combina gesture responder e coordinate.

import { PanResponder, View, Animated } from 'react-native';
import { useRef } from 'react';
const Dragabile = () => {
const pan = useRef(new Animated.ValueXY()).current;
const panResponder = useRef(
PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: Animated.event(
[null, { dx: pan.x, dy: pan.y }],
{ useNativeDriver: false }
),
onPanResponderRelease: () => {
pan.extractOffset(); // mantiene posizione
},
})
).current;
return (
<Animated.View
style={{
transform: [{ translateX: pan.x }, { translateY: pan.y }],
width: 80, height: 80,
borderRadius: 40,
backgroundColor: '#3498db',
}}
{...panResponder.panHandlers}
/>
);
};

const Swipeable = () => {
const panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderRelease: (_, gestureState) => {
const { dx, dy } = gestureState;
if (Math.abs(dx) > Math.abs(dy)) {
if (dx > 50) console.log('SWIPE DESTRA');
else if (dx < -50) console.log('SWIPE SINISTRA');
} else {
if (dy > 50) console.log('SWIPE GIÙ');
else if (dy < -50) console.log('SWIPE SU');
}
},
});
return (
<View
style={{ width: 200, height: 200, backgroundColor: 'lightblue' }}
{...panResponder.panHandlers}
/>
);
};

{
dx: number, // spostamento X dal punto di partenza
dy: number, // spostamento Y
vx: number, // velocità X
vy: number, // velocità Y
moveX: number, // posizione X assoluta
moveY: number, // posizione Y assoluta
numberActiveTouches: number, // dita sullo schermo
}

APIUso
Gesture ResponderCatturare tocchi su View
PanResponderDrag, swipe, gesture complete
gestureStatedx, dy, vx, vy per analisi

Crea una card che:

  1. Puoi trascinare orizzontalmente
  2. Se rilasciata con dx > 100 → si sposta a destra
  3. Se rilasciata con dx < -100 → si sposta a sinistra
  4. Altrimenti torna al centro (animazione)