Saltar al contenido

Gestos y dibujo personalizado

Responde al tacto con gestos (tap, drag, magnify) y dibuja lo que imagines con Shapes, Path y Canvas. La interfaz que va más allá de los controles estándar.

Los controles estándar cubren mucho, pero las apps memorables tienen toques propios: una tarjeta que arrastras, un gráfico dibujado a medida, una interacción táctil única. Para eso SwiftUI te da gestos y un lienzo de dibujo.

  • Gestos simples: tap, long press.
  • Arrastrar con DragGesture y @GestureState.
  • Formas listas y Path a medida.
  • Dibujo eficiente con Canvas.

Gestos simples

Los más comunes son modificadores directos:

SWIFT
Text("Tócame")    .onTapGesture { print("tap") }    .onLongPressGesture { print("mantenido") }// tap doble o con posiciónCircle()    .onTapGesture(count: 2) { print("doble tap") }

Arrastrar: DragGesture

Para gestos con estado continuo (arrastrar), usas .gesture(...) con DragGesture. @GestureState guarda el desplazamiento solo mientras dura el gesto:

SWIFT
struct Arrastrable: View {    @State private var posicion = CGSize.zero    @GestureState private var arrastre = CGSize.zero    var body: some View {        Circle()            .frame(width: 80, height: 80)            .offset(x: posicion.width + arrastre.width,                    y: posicion.height + arrastre.height)            .gesture(                DragGesture()                    .updating($arrastre) { valor, estado, _ in                        estado = valor.translation      // mientras arrastras                    }                    .onEnded { valor in                        posicion.width += valor.translation.width                        posicion.height += valor.translation.height                    }            )    }}

@GestureState se resetea solo

@GestureState vuelve a su valor inicial automáticamente cuando el gesto termina. Por eso el patrón es: acumula el resultado final en un @State normal (posicion) en onEnded, y usa el @GestureState (arrastre) solo para el movimiento en curso. Así el objeto se queda donde lo soltaste.

Formas y Path

SwiftUI trae formas listas: Circle, Rectangle, RoundedRectangle, Capsule, Ellipse. Y para lo tuyo, Path dibuja líneas y curvas:

SWIFT
Path { p in    p.move(to: CGPoint(x: 0, y: 100))    p.addLine(to: CGPoint(x: 100, y: 0))    p.addLine(to: CGPoint(x: 200, y: 100))    p.closeSubpath()}.fill(.orange)

Canvas: dibujo eficiente

Cuando necesitas dibujar muchos elementos (partículas, gráficos, visualizaciones), Canvas es un lienzo de alto rendimiento que dibuja en modo inmediato, sin crear una vista por elemento:

SWIFT
Canvas { context, size in    for i in 0..<50 {        let x = Double.random(in: 0...size.width)        let y = Double.random(in: 0...size.height)        let punto = Path(ellipseIn: CGRect(x: x, y: y, width: 6, height: 6))        context.fill(punto, with: .color(.blue))    }}

¿Vistas o Canvas?

Para unos pocos elementos interactivos, usa vistas normales (Circle, Rectangle): son componibles y animables. Para cientos o miles de elementos de dibujo (un gráfico denso, un sistema de partículas, un editor de trazos), Canvas es muchísimo más rápido porque no crea una vista SwiftUI por cada píxel: dibuja directo. Elegir la herramienta correcta según la cantidad es lo que separa una interfaz fluida de una que se arrastra.

Interacción y dibujo a medida

  1. Añade .onTapGesture a una vista y cambia su color al tocarla.
  2. Haz un círculo arrastrable con DragGesture y @GestureState.
  3. Dibuja un triángulo con Path.
  4. Usa Canvas para dibujar 30 círculos en posiciones aleatorias.