Origem
Recentemente quis portar meu mini-programa WeChat "花瓣单词挑战" para iOS. Esse jogo envolve formar palavras tocando letras em pétalas. Desenhar pétalas com CSS era simples, mas migrar para SwiftUI foi desafiador.
Como conhecedor intermediário de SwiftUI - tendo criado apenas alguns apps básicos - não sabia por onde começar a desenhar uma pétala. Pesquisei "SwiftUI pétala" no Google e encontrei este artigo. Embora não fosse exatamente o que queria, deu-me um ponto de partida.
O que é o Shape Protocol?
Resumidamente, o Shape Protocol do SwiftUI permite criar formas personalizadas. Basta implementar o método path(in rect: CGRect) -> Path
para definir o desenho.
Primeira tentativa: Desenhando arcos com addArc
O artigo usava o 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 o código, testei no Xcode com fundo vermelho:
struct ShapTest: View {
var body: some View {
DaisyPental()
.fill(.yellow.gradient)
.frame(width: 110, height: 20)
.background(.red) // Fundo vermelho para visualização
}
}
Sistema de coordenadas do SwiftUI é contra-intuitivo
Atenção para esta particularidade:
- Origem no canto superior esquerdo: Não no inferior
- Eixo X: Positivo para direita (normal)
- Eixo Y: Positivo para baixo (contra-intuitivo!)
Portanto:
rect.minX
,rect.minY
→ Canto superior esquerdorect.maxX
,rect.maxY
→ Canto inferior direitorect.midX
,rect.midY
→ Centro
Você pode experimentar alterando valores no path.move
enquanto observa o preview.
Ângulos do addArc são mais contra-intuitivos
A definição angular do addArc
é peculiar:
- 0° → Direita
- 90° → Baixo (Não cima!)
- 180° → Esquerda
- 270° → Cima
Diferente do sistema matemático padrão.
addQuadCurve: Ferramenta essencial para curvas
Percebi que addArc
não servia para minha pétala. Encontrei addQuadCurve
no YouTube e funcionou melhor:
path.addQuadCurve(
to: CGPoint, // Ponto final
control: CGPoint // Ponto de controle
)
- Ponto inicial: Posição atual
- Ponto final: Destino da curva
- Ponto de controle: Define a curvatura
Ajustar o ponto de controle altera visualmente a curva.
Minha implementação final da pétala
Após experimentação, cheguei nesta forma:
import SwiftUI
struct PetalShape: Shape {
func path(in rect: CGRect) -> Path {
Path { path in
// Ponto inicial
path.move(to: CGPoint(x: rect.minX + 30, y: rect.minY + 30))
// Curva esquerda
path.addQuadCurve(
to: CGPoint(x: rect.minX + 30, y: rect.minY - 30),
control: CGPoint(x: rect.minX - 10, y: rect.minY)
)
// Ponta da pétala
path.addQuadCurve(
to: CGPoint(x: rect.maxX * 1.8, y: rect.minY),
control: CGPoint(x: rect.midX + 40, y: -rect.maxY + 30)
)
// Lado direito (retorno ao início)
path.addQuadCurve(
to: CGPoint(x: rect.minX + 30, y: rect.minY + 30),
control: CGPoint(x: rect.midX + 40, y: rect.maxY - 30)
)
}
}
}
Exemplo de uso:
struct ShapeTest: View {
var body: some View {
PetalShape()
.fill(.yellow.gradient)
.frame(width: 110, height: 110)
}
}
Próximo passo: Compor a flor completa
Com uma pétala pronta, compor a flor é simples:
- Duplicar várias pétalas
- Rotacionar com
rotationEffect
- Ajustar posição com
offset
- Combinar em uma flor
Lições aprendidas
Conclusões importantes:
- Sistema de coordenadas: Particularmente contra-intuitivo
- addQuadCurve > addArc: Superior para curvas naturais
- Ponto de controle crucial: Experimentação é essencial
- Preview ao vivo indispensável: Use constantemente o Canvas
Conclusão
Finalmente criei o formato da pétala e continuo o desenvolvimento do "花瓣单词挑战" para iOS, visando lançamento em breve.
Escrevi este artigo para documentar o processo. Se trabalha com formas personalizadas em SwiftUI, espero que ajude!