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ón
Circle()
.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 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))
}
}
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.
- 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.