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
DragGesturey@GestureState. - Formas listas y
Patha medida. - Dibujo eficiente con
Canvas.
Gestos simples
Los más comunes son modificadores directos:
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:
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:
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:
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
- Añade
.onTapGesturea una vista y cambia su color al tocarla. - Haz un círculo arrastrable con
DragGesturey@GestureState. - Dibuja un triángulo con
Path. - Usa
Canvaspara dibujar 30 círculos en posiciones aleatorias.