Errores al dibujar pétalos de flores con SwiftUI: práctica del protocolo de forma

Registro detallado del proceso completo de dibujo de formas de pétalos personalizadas utilizando el protocolo de formas SwiftUI, incluidos consejos prácticos como addQuadCurve y el sistema de coordenadas

Origen

Recientemente quise llevar mi miniprograma de WeChat "花瓣单词挑战" a iOS. Este miniprograma es un juego donde formas palabras tocando letras en pétalos. Dibujar pétalos con CSS era sencillo, pero al cambiar a SwiftUI fue un dolor de cabeza.

Como principiante en SwiftUI, habiendo creado solo algunas apps simples antes, no tenía idea de cómo dibujar un pétalo. Busqué "SwiftUI pétalo" en Google y encontré este artículo. Aunque no era exactamente lo que buscaba, me dio un punto de partida.

¿Qué es el Shape Protocol?

En resumen, el Shape Protocol de SwiftUI es una herramienta para crear formas personalizadas. Solo necesitas implementar el método path(in rect: CGRect) -> Path para definir cómo dibujar la forma.

Primer intento: Dibujar arcos con addArc

El artículo usaba el método addArc:

struct DaisyPental: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        path.move(to: CGPoint(x: rect.minX, y: rect.midY))
        path.addArc(
            center: CGPoint(x: rect.maxX, y: rect.midY), 
            radius: rect.maxX*(1/11),
            startAngle: .degrees(90),
            endAngle: .degrees(270),
            clockwise: true
        )
        return path
    }
}

Para entender el código, lo probé en Xcode con un fondo rojo:

struct ShapTest: View {
    var body: some View {
        DaisyPental()
            .fill(.yellow.gradient)
            .frame(width: 110, height: 20)
            .background(.red)  // Fondo rojo para visualización
    }
}

El sistema de coordenadas de SwiftUI es contraintuitivo

Alerta importante: el sistema de coordenadas funciona diferente:

  • Origen en superior izquierda: No en inferior izquierda
  • Eje X: Positivo hacia la derecha (normal)
  • Eje Y: Positivo hacia abajo (¡contraintuitivo!)

Por tanto:

  • rect.minX, rect.minY → Esquina superior izquierda
  • rect.maxX, rect.maxY → Esquina inferior derecha
  • rect.midX, rect.midY → Centro

Puedes experimentar modificando valores en path.move con el preview de Xcode.

Los ángulos de addArc son más contraintuitivos

La definición angular de addArc es peculiar:

  • 0° → Derecha
  • 90° → Abajo (¡No arriba!)
  • 180° → Izquierda
  • 270° → Arriba

Es completamente diferente al sistema matemático estándar.

addQuadCurve: La herramienta para curvas

Descubrí que addArc no servía para mi pétalo. Vi addQuadCurve en YouTube y funcionó mejor:

path.addQuadCurve(
    to: CGPoint,      // Punto final
    control: CGPoint  // Punto de control
)
  • Punto inicial: Posición actual
  • Punto final: Destino de la curva
  • Punto de control: Determina la curvatura

El punto de control modifica la curva visualmente.

Mi implementación final del pétalo

Tras experimentar, llegué a esta forma:

import SwiftUI

struct PetalShape: Shape {
    func path(in rect: CGRect) -> Path {
        Path { path in
            // Punto inicial
            path.move(to: CGPoint(x: rect.minX + 30, y: rect.minY + 30))
            
            // Curva izquierda
            path.addQuadCurve(
                to: CGPoint(x: rect.minX + 30, y: rect.minY - 30),
                control: CGPoint(x: rect.minX - 10, y: rect.minY)
            )
            
            // Punta del pétalo
            path.addQuadCurve(
                to: CGPoint(x: rect.maxX * 1.8, y: rect.minY),
                control: CGPoint(x: rect.midX + 40, y: -rect.maxY + 30)
            )
            
            // Lado derecho (regreso al inicio)
            path.addQuadCurve(
                to: CGPoint(x: rect.minX + 30, y: rect.minY + 30),
                control: CGPoint(x: rect.midX + 40, y: rect.maxY - 30)
            )
        }
    }
}

Ejemplo de uso:

struct ShapeTest: View {
    var body: some View {
        PetalShape()
            .fill(.yellow.gradient)
            .frame(width: 110, height: 110)
    }
}

Siguiente paso: Componer la flor completa

Con un pétalo listo, crear la flor es sencillo:

  1. Duplicar varios pétalos
  2. Rotar con rotationEffect
  3. Ajustar posición con offset
  4. Combinarlos en una flor

Lecciones aprendidas

Conclusiones clave:

  • Sistema de coordenadas: Especialmente contraintuitivo
  • addQuadCurve > addArc: Superior para curvas naturales
  • Punto de control crucial: Experimentar es esencial
  • Vista previa indispensable: Usar Canvas constantemente

Finalmente

Logré crear el pétalo y continuaré con "花瓣单词挑战" para iOS, apuntando a un lanzamiento pronto.

Escribí esto para documentar el proceso. Si trabajas con formas personalizadas en SwiftUI, ¡espero que te ayude!

Referencias