Criando formas SwiftUI complexas usando ferramentas de design
Uma maneira fácil de converter design em código
SwiftUI nos dá 5 formas internas para uso em nossos projetos.
Eles são Rectangle, RoundedRectangle(que tem um parâmetro de raio de canto), Capsule, Ellipsee Circle.
Vamos vê-lo em ação:
struct ShapesView: View {
var body: some View {
VStack (spacing: 10) {
Rectangle()
.fill(.pink)
.frame(width: 100, height: 50)
RoundedRectangle(cornerRadius: 10, style: .continuous)
.fill(.purple)
.frame(width: 100, height: 100)
Capsule()
.fill(.blue)
.frame(width: 150, height: 150)
Ellipse()
.fill(.red)
.frame(width: 150, height: 100)
Circle()
.fill(.green)
.frame(width: 150, height: 250)
}
}
}
Shapese Pathssão primitivas poderosas que podem ser usadas em muitas situações.
No entanto, há casos em que formas mais complexas são necessárias. A Apple oferece suporte para desenho personalizado com duas ferramentas integradas: Pathse Shapes.
Uma Forma é composta de uma série de Caminhos. Paul Hudson tem uma ótima introdução a essas ferramentas.
Vamos verificar como fica em ação e desenhar um hexágono simples usando o Shapeprotocolo.
struct Hexagon: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let width = rect.width
let height = rect.height
let x = rect.midX
let y = rect.midY
let side = min(width, height) / 2.0
let a = side / 2.0
let b = side * sqrt(3.0) / 2.0
path.move(to: CGPoint(x: x, y: y - side))
path.addLine(to: CGPoint(x: x + a, y: y - b))
path.addLine(to: CGPoint(x: x + a, y: y + b))
path.addLine(to: CGPoint(x: x, y: y + side))
path.addLine(to: CGPoint(x: x - a, y: y + b))
path.addLine(to: CGPoint(x: x - a, y: y - b))
path.closeSubpath()
return path
}
}
Hexagon created using SwiftUI’s shape method.
Como exemplo, vamos criar um widget neomórfico para nosso aplicativo de rastreamento de hábitos:
Para obter um efeito de profundidade para o número 12, simplesmente usar Text(“12”)modificadores de sombra interna e regular não será suficiente. Precisamos criá-lo usando Shapes.
Para fazer isso, vamos usar uma ferramenta de gráficos vetoriais como Figma (grátis) ou Sketch (pago) para criar as formas.
Primeiro, coloque uma captura de tela de um objeto que você deseja replicar como uma Forma no plano de fundo.
2. Em seguida, comece a desenhar números usando curvas (tecla de atalho “V” no Sketch) na parte superior da captura de tela.
3. Exporte sua Forma criada no formato SVG.
4. Abra o arquivo salvo TextEditore copie o código
5. Em seguida, abrahttps://svg-to-swiftui.quassum.com/, (É gratuito, mas considere fazer uma doação como forma de expressar gratidão), cole nosso código no bloco esquerdo e clique em converter. Você pode finalmente copiar o resultado.
6. Adicione o recém-gerado Shapeao seu código.
struct MyCustomShape: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let width = rect.size.width
let height = rect.size.height
path.move(to: CGPoint(x: 0.19277*width, y: 0.92051*height))
path.addCurve(to: CGPoint(x: 0.2653*width, y: 0.98843*height), control1: CGPoint(x: 0.20687*width, y: 0.96579*height), control2: CGPoint(x: 0.23104*width, y: 0.98843*height))
path.addCurve(to: CGPoint(x: 0.33219*width, y: 0.92647*height), control1: CGPoint(x: 0.29955*width, y: 0.98843*height), control2: CGPoint(x: 0.32185*width, y: 0.96777*height))
path.addLine(to: CGPoint(x: 0.33219*width, y: 0.087*height))
path.addCurve(to: CGPoint(x: 0.32684*width, y: 0.06301*height), control1: CGPoint(x: 0.33219*width, y: 0.07844*height), control2: CGPoint(x: 0.33033*width, y: 0.07008*height))
path.addCurve(to: CGPoint(x: 0.24718*width, y: 0.0101*height), control1: CGPoint(x: 0.30949*width, y: 0.02773*height), control2: CGPoint(x: 0.28294*width, y: 0.0101*height))
path.addCurve(to: CGPoint(x: 0.2008*width, y: 0.02081*height), control1: CGPoint(x: 0.23579*width, y: 0.0101*height), control2: CGPoint(x: 0.21869*width, y: 0.01038*height))
path.addCurve(to: CGPoint(x: 0.00999*width, y: 0.19972*height), control1: CGPoint(x: 0.17119*width, y: 0.03807*height), control2: CGPoint(x: 0.10759*width, y: 0.0977*height))
path.addCurve(to: CGPoint(x: 0.00999*width, y: 0.29059*height), control1: CGPoint(x: -0.00333*width, y: 0.23402*height), control2: CGPoint(x: -0.00333*width, y: 0.26431*height))
path.addCurve(to: CGPoint(x: 0.05958*width, y: 0.31902*height), control1: CGPoint(x: 0.0233*width, y: 0.31686*height), control2: CGPoint(x: 0.03983*width, y: 0.32634*height))
path.addLine(to: CGPoint(x: 0.18235*width, y: 0.21522*height))
path.addCurve(to: CGPoint(x: 0.19176*width, y: 0.21836*height), control1: CGPoint(x: 0.18557*width, y: 0.21249*height), control2: CGPoint(x: 0.18979*width, y: 0.2139*height))
path.addCurve(to: CGPoint(x: 0.19277*width, y: 0.2233*height), control1: CGPoint(x: 0.19242*width, y: 0.21985*height), control2: CGPoint(x: 0.19277*width, y: 0.22156*height))
path.addLine(to: CGPoint(x: 0.19277*width, y: 0.92051*height))
path.addLine(to: CGPoint(x: 0.19277*width, y: 0.92051*height))
path.closeSubpath()
path.move(to: CGPoint(x: 0.69057*width, y: 0.7981*height))
path.addCurve(to: CGPoint(x: 0.97169*width, y: 0.34296*height), control1: CGPoint(x: 0.86713*width, y: 0.57524*height), control2: CGPoint(x: 0.96084*width, y: 0.42353*height))
path.addCurve(to: CGPoint(x: 0.73689*width, y: 0.00042*height), control1: CGPoint(x: 1.01286*width, y: 0.03744*height), control2: CGPoint(x: 0.79508*width, y: 0.00549*height))
path.addCurve(to: CGPoint(x: 0.54637*width, y: 0.09386*height), control1: CGPoint(x: 0.67965*width, y: -0.00457*height), control2: CGPoint(x: 0.60044*width, y: 0.03569*height))
path.addCurve(to: CGPoint(x: 0.49384*width, y: 0.25608*height), control1: CGPoint(x: 0.50625*width, y: 0.13702*height), control2: CGPoint(x: 0.48874*width, y: 0.19109*height))
path.addCurve(to: CGPoint(x: 0.54637*width, y: 0.32849*height), control1: CGPoint(x: 0.49732*width, y: 0.30435*height), control2: CGPoint(x: 0.51483*width, y: 0.32849*height))
path.addCurve(to: CGPoint(x: 0.60648*width, y: 0.29057*height), control1: CGPoint(x: 0.56918*width, y: 0.32849*height), control2: CGPoint(x: 0.58922*width, y: 0.31585*height))
path.addLine(to: CGPoint(x: 0.60647*width, y: 0.29056*height))
path.addCurve(to: CGPoint(x: 0.6279*width, y: 0.24067*height), control1: CGPoint(x: 0.61618*width, y: 0.27632*height), control2: CGPoint(x: 0.6235*width, y: 0.25929*height))
path.addCurve(to: CGPoint(x: 0.73689*width, y: 0.16131*height), control1: CGPoint(x: 0.6404*width, y: 0.18776*height), control2: CGPoint(x: 0.67673*width, y: 0.16131*height))
path.addCurve(to: CGPoint(x: 0.80924*width, y: 0.39983*height), control1: CGPoint(x: 0.77971*width, y: 0.16131*height), control2: CGPoint(x: 0.88867*width, y: 0.21187*height))
path.addCurve(to: CGPoint(x: 0.50041*width, y: 0.82587*height), control1: CGPoint(x: 0.77745*width, y: 0.47504*height), control2: CGPoint(x: 0.58125*width, y: 0.70046*height))
path.addCurve(to: CGPoint(x: 0.48514*width, y: 0.9152*height), control1: CGPoint(x: 0.47311*width, y: 0.86822*height), control2: CGPoint(x: 0.48396*width, y: 0.90852*height))
path.addCurve(to: CGPoint(x: 0.5197*width, y: 0.96465*height), control1: CGPoint(x: 0.48792*width, y: 0.93094*height), control2: CGPoint(x: 0.49944*width, y: 0.94742*height))
path.addCurve(to: CGPoint(x: 0.53583*width, y: 0.97096*height), control1: CGPoint(x: 0.52455*width, y: 0.96877*height), control2: CGPoint(x: 0.53013*width, y: 0.97096*height))
path.addLine(to: CGPoint(x: 0.94174*width, y: 0.97096*height))
path.addCurve(to: CGPoint(x: 0.96928*width, y: 0.95989*height), control1: CGPoint(x: 0.95149*width, y: 0.97096*height), control2: CGPoint(x: 0.96104*width, y: 0.96712*height))
path.addCurve(to: CGPoint(x: 0.99372*width, y: 0.89749*height), control1: CGPoint(x: 0.98557*width, y: 0.94557*height), control2: CGPoint(x: 0.99372*width, y: 0.92477*height))
path.addCurve(to: CGPoint(x: 0.96211*width, y: 0.82232*height), control1: CGPoint(x: 0.99372*width, y: 0.86647*height), control2: CGPoint(x: 0.98318*width, y: 0.84142*height))
path.addCurve(to: CGPoint(x: 0.94337*width, y: 0.81459*height), control1: CGPoint(x: 0.95654*width, y: 0.81728*height), control2: CGPoint(x: 0.95002*width, y: 0.81459*height))
path.addLine(to: CGPoint(x: 0.69517*width, y: 0.81459*height))
path.addCurve(to: CGPoint(x: 0.68833*width, y: 0.8051*height), control1: CGPoint(x: 0.69139*width, y: 0.81458*height), control2: CGPoint(x: 0.68833*width, y: 0.81033*height))
path.addCurve(to: CGPoint(x: 0.69057*width, y: 0.7981*height), control1: CGPoint(x: 0.68833*width, y: 0.80243*height), control2: CGPoint(x: 0.68915*width, y: 0.79989*height))
path.closeSubpath()
return path
}
}
8. Finalmente, podemos aplicar todos os modificadores a ele como a um Shapeobjeto regular e obter bons números com um efeito de profundidade.
MyCustomShape()
.frame(width: 100, height: 100)
.overlay(
MyCustomShape()
.fill(
.shadow(.inner(color: bgl, radius: 5, x: -5, y: 5))
.shadow(.inner(color: bgd, radius: 5, x: 5, y: -5)))
.foregroundColor(colorbg))
É isso! Simples e direto.
Imagine ter que escrever todas essas linhas de código você mesmo. Espero que isso economize algum tempo para que você possa usá-lo para alguma codificação interessante. Até a próxima vez!





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)