DRAGGESTURE en SWIFTUI en Español
DragGesture en SwiftUI

DRAGGESTURE en SWIFTUI en Español

DragGesture en SwiftUI 2.0 nos sirve para ejecutar alguna acción cuando un user arrastra una vista. Podemos usar distintos modificadores como .onChanged o .onEnded para realizar las acciones que queramos.

SwiftBeta
Aprende SwiftUI desde cero

En SwiftUI 2.0 podemos añadir gestos a nuestras vistas, en el ejemplo de hoy vamos a ver a cómo mover un rectángulo por nuestra pantalla. Lo único que tenemos que hacer será tocarlo con el dedo y arrastrarlo a la posición que queramos.

DragGesture en código

Lo primero que vamos hacer es añadir un rectángulo a nuestra vista:

struct ContentView: View {
    var body: some View {
        RoundedRectangle(cornerRadius: 20)
            .frame(width: 100, height: 100)
    }
}

A continuación, vamos usar el modificador .offset el cual nos permite cambiar la posición de nuestra vista, en este caso vamos hacer que el rectángulo en lugar de estar en la posición X: 0 y Y:0, (que es la posición por defecto al añadir una vista en SwiftUI) esté en Y:-200.

struct ContentView: View {    
    var body: some View {
        RoundedRectangle(cornerRadius: 20)
            .frame(width: 100, height: 100)
            .offset(y: -200)
    }
}

Añadiendo este offset de -200 en el eje Y vemos como la vista está en la parte superior de la pantalla.

¿Por qué te explico esto? Por que lo que vamos hacer es detectar en qué posición tenemos el dedo y usar esas coordenadas para mover nuestro rectángulo, y ¿cómo podemos escuchar estos cambios? usando el modificador .gesture e instanciando DragGesture (que es el tipo de gesto que queremos usar).
Lo que haremos será usarlo en nuestro rectángulo de la siguiente manera:

struct ContentView: View {    
    var body: some View {
        RoundedRectangle(cornerRadius: 20)
            .frame(width: 100, height: 100)
            .offset(x: -100, y: -200)
            .gesture(
                DragGesture()
                    .onChanged({ (value) in
                        print("Value \(value)")
                    })
            )
    }
}

Cuando usamos el DragGesture podemos escuchar cuando la posición del dedo cambia en la pantalla, que es lo que recibimos como value dentro de este closure.

Si compilamos la app y movemos el rectángulo vemos por consola como se printa información relacionada con nuestro DragGesture: location, velocidad, start location, etc

Esto está muy bien, pero el rectángulo no se mueve. Lo que tenemos que hacer ahora es crear una propiedad @State de tipo CGSize donde iremos almacenando la información que recibimos de nuestro DragGesture en cada onChange y luego esa información se la proporcionaremos a nuestro modificador .offset, que se encargará de mover nuestro rectángulo en cada cambio de posición de nuestro dedo:

struct ContentView: View {
    
    @State var dragOffset: CGSize = .zero
    
    var body: some View {
        RoundedRectangle(cornerRadius: 20)
            .frame(width: 100, height: 100)
            .offset(x: dragOffset.width, y: dragOffset.height)
            .gesture(
                DragGesture()
                    .onChanged({ (value) in
                        self.dragOffset = value.translation
                    })
            )
    }
}
recuerda: cada cambio que hagamos en la propiedad dragOffset, actualizará la posición del modificador .offset automáticamente

Ahora si, compilamos la app, el rectangulo se mueve a la posición donde tengamos el dedo.
Podemos usar más modificadores dentro del DragGesture, como el .onEnded. Cuando el user deje de mover el rectángulo, el closure del .onEnded recibirá un valor pero lo omitiremos y asignaremos a dragOffset la posición .zero, así el rectángulo volverá a la posición inicial:

struct ContentView: View {
    
    @State var dragOffset: CGSize = .zero
    
    var body: some View {
        RoundedRectangle(cornerRadius: 20)
            .frame(width: 100, height: 100)
            .offset(x: dragOffset.width, y: dragOffset.height)
            .gesture(
                DragGesture()
                    .onChanged({ (value) in
                        self.dragOffset = value.translation
                    })
                    .onEnded({ (value) in
                        self.dragOffset = .zero
                    })
            )
    }
}

Para hacerlo un poquito más suave, podemos usar la función withAnimation con una animación spring para que cuando el user suelte el rectangulo, éste vuelva a su posición original con una animación:

struct ContentView: View {
    
    @State var dragOffset: CGSize = .zero
    
    var body: some View {
        RoundedRectangle(cornerRadius: 20)
            .frame(width: 100, height: 100)
            .offset(x: dragOffset.width, y: dragOffset.height)
            .gesture(
                DragGesture()
                    .onChanged({ (value) in
                        self.dragOffset = value.translation
                    })
                    .onEnded({ (value) in
                        withAnimation(.spring()) {
                            self.dragOffset = .zero
                        }
                    })
            )
    }
}
Código para crear un DragGesture en SwiftUI

Hasta aquí el post de DragGesture en SwiftUI!

Hasta aquí el post de hoy, gracias por leernos! 🤓
👉👉 SUSCRÍBETE al CANAL de youtube
Si tienes preguntas no dudes en contactar con nosotros a través de Twitter

Si quieres seguir aprendiendo sobre SwiftUI, Swift, Xcode, o cualquier tema relacionado con el ecosistema Apple


SwiftUI desde cero