Scaling UIBezierPath for SwiftUI Shapes
Quick tip for today! What happens when you get an SVG output from your designer or design program? How do you convert that over into a custom SwiftUI Shape
struct?
Converting SVG Path
- First you can use the popular tool SwiftVG created by Mike Engel to convert the SVG path code into Swift UIBezierPath code.
- From there you'll need to scale
UIBezierPath
to fit theCGRect
that is provided to your customShape
struct in thepath(in rect:)
function. You can do this using an extension onPath
to apply aCGAffineTransform
. From there you can return the Path as normal.
struct Wave: Shape {
func path(in rect: CGRect) -> Path {
let path = UIBezierPath()
// Path drawing code here
// ...
return Path(path.cgPath).scaled(for: rect)
}
}
extension Path {
func scaled(for rect: CGRect) -> Path {
let scaleX = rect.width/boundingRect.width
let scaleY = rect.height/boundingRect.height
let scale = min(scaleX, scaleY)
return applying(CGAffineTransform(scaleX: scale, y: scale))
}
}
Scaling in X or Y Direction
If you'd like to further scale the path in only one direction, then you can again write an extension for Path
. By performing a CGAffineTransform
on the Path
you can achieve the desired result.
struct Wave: Shape {
func path(in rect: CGRect) -> Path {
let path = UIBezierPath()
// Path drawing code here
// ...
return Path(path.cgPath).scaled(for: rect).scale(x: 1, y: 5)
}
}
extension Path {
func scale(x: CGFloat, y: CGFloat) -> Path {
return applying(CGAffineTransform(scaleX: x, y: y))
}
}