Permitir arrastrar elementos por la pantalla en React Native

Tiempo de lectura: 2 minutos

Hoy vamos a crear un componente que nos permitirá arrastrar otros elementos por la pantalla usando React Native.

Lo primero que haremos es crear el componete que llamaremos DragComponent.tsx y añadiremos la lógica que nos permita arrastrar:

import React, { useRef, ReactNode, useState } from 'react';
import { Animated, PanResponder, StyleProp, ViewStyle } from 'react-native';

interface DragableProps {
    children: ReactNode;
    style?: StyleProp<ViewStyle>;
}

const DragComponent: React.FC<DraggableProps> = ({ children, style }) => {
    const [offset, setOffset] = useState({ x: 0, y: 0 });
    const pan = useRef(new Animated.ValueXY()).current;
   
    const panResponder = PanResponder.create({
        onStartShouldSetPanResponder: () => true,
        onPanResponderMove: (_, gesture) => {
            pan.setValue({ x: gesture.dx + offset.x, y: gesture.dy + offset.y });
        },
        onPanResponderRelease: (_, gesture) => {
            setOffset({ x: gesture.dx + offset.x, y: gesture.dy + offset.y });
        },
    });

    return (
        <Animated.View
            {...panResponder.panHandlers}
            style={[
                {
                    transform: [{ translateX: pan.x }, { translateY: pan.y }],
                },
                style,
            ]}
        >
            {children}
        </Animated.View>
    );
};

export default DragComponent;

Ahora voy a explicar el código:

  1. Importaciones:
   import React, { useRef, ReactNode, useState } from 'react';
   import { Animated, PanResponder, StyleProp, ViewStyle } from 'react-native';
  • Importamos las bibliotecas necesarias de React y React Native, incluyendo Animated para animaciones y PanResponder para manejar gestos de arrastre.
  1. Definición del componente DragComponent:
   const DragComponent: React.FC<DraggableProps> = ({ children, style }) => {
  • Declaramos el componente DragComponent como una función de React que acepta props (children y style en este caso).
  1. Estado del desplazamiento (offset):
   const [offset, setOffset] = useState({ x: 0, y: 0 });
  • Definimos el estado offset utilizando el hook useState. Este estado representa la posición actual del componente en relación con su posición original.
  1. Referencia animada (pan):
   const pan = useRef(new Animated.ValueXY()).current;
  • Creamos una referencia animada pan utilizando el hook useRef. Esta referencia se utiliza para controlar la posición del componente durante el arrastre.
  1. Manejador de gestos (panResponder):
   const panResponder = PanResponder.create({
       onStartShouldSetPanResponder: () => true,
       onPanResponderMove: (_, gesture) => {
           pan.setValue({ x: gesture.dx + offset.x, y: gesture.dy + offset.y });
       },
       onPanResponderRelease: (_, gesture) => {
           setOffset({ x: gesture.dx + offset.x, y: gesture.dy + offset.y });
       },
   });
  • Creamos un manejador de gestos utilizando PanResponder.create(). Este manejador controla el comportamiento del componente durante el arrastre y al soltarlo.
  • En onPanResponderMove, actualizamos continuamente la posición del componente (pan) sumando el desplazamiento (dx y dy) del gesto con el desplazamiento actual (offset).
  • En onPanResponderRelease, actualizamos el offset del componente con el desplazamiento final del gesto, lo que determina la nueva posición del componente como la posición de inicio para el próximo arrastre.
  1. Renderizado del componente:
   return (
       <Animated.View
           {...panResponder.panHandlers}
           style={[
               {
                   transform: [{ translateX: pan.x }, { translateY: pan.y }],
               },
               style,
           ]}
       >
           {children}
       </Animated.View>
   );
  • Renderizamos el componente Animated.View con propiedades y gestores de eventos del panResponder.
  • La propiedad transform se utiliza para aplicar la transformación de traslación al componente basada en los valores x e y de la referencia animada pan.
  • Pasamos las props children y style al componente Animated.View.

Para utilizarlo solo tendremos que envolver nuestro componente con este:

<DragComponent>
      <Text> Mover </Text>
</DragComponent>

1 comentario en «Permitir arrastrar elementos por la pantalla en React Native»

Deja un comentario