import SwiftUI
struct ShapeView: Shape {
let besier: UIBezierPath // Stored property 'besier' of 'Sendable'-conforming struct 'ShapeView' has non-sendable type 'UIBezierPath'
let pathBounds: CGRect
func path(in rect: CGRect) -> Path {
let pointScale = 1 / ((rect.width >= rect.height) ? max(pathBounds.height, pathBounds.width) : min(pathBounds.height, pathBounds.width))
let path = Path(besier.cgPath).applying(CGAffineTransform(scaleX: pointScale, y: pointScale))
let multiplier = min(rect.width, rect.height)
return path.applying(CGAffineTransform(scaleX: multiplier, y: multiplier))
}
}
Can you just store a Path
?
I am not sure. The UIBezierPath
is created from converting the SVG:
static var swiftLogo: UIBezierPath {
let shape = UIBezierPath()
shape.move(to: CGPoint(x: 29.89, y: 33.05))
shape.addCurve(to: CGPoint(x: 12.35, y: 33.25), controlPoint1: CGPoint(x: 25.22, y: 35.74), controlPoint2: CGPoint(x: 18.8, y: 36.02))
shape.addCurve(to: CGPoint(x: 0, y: 22.69), controlPoint1: CGPoint(x: 7.12, y: 31.03), controlPoint2: CGPoint(x: 2.78, y: 27.14))
shape.addCurve(to: CGPoint(x: 4.56, y: 25.47), controlPoint1: CGPoint(x: 1.33, y: 23.8), controlPoint2: CGPoint(x: 2.89, y: 24.69))
shape.addCurve(to: CGPoint(x: 22.58, y: 25.48), controlPoint1: CGPoint(x: 11.23, y: 28.59), controlPoint2: CGPoint(x: 17.89, y: 28.38))
shape.addCurve(to: CGPoint(x: 22.58, y: 25.47), controlPoint1: CGPoint(x: 22.58, y: 25.47), controlPoint2: CGPoint(x: 22.58, y: 25.47))
shape.addCurve(to: CGPoint(x: 6.01, y: 8.23), controlPoint1: CGPoint(x: 15.9, y: 20.35), controlPoint2: CGPoint(x: 10.23, y: 13.68))
shape.addCurve(to: CGPoint(x: 3.78, y: 5.23), controlPoint1: CGPoint(x: 5.12, y: 7.34), controlPoint2: CGPoint(x: 4.45, y: 6.23))
shape.addCurve(to: CGPoint(x: 19.91, y: 17.46), controlPoint1: CGPoint(x: 8.9, y: 9.9), controlPoint2: CGPoint(x: 17.02, y: 15.79))
shape.addCurve(to: CGPoint(x: 8.56, y: 3.23), controlPoint1: CGPoint(x: 13.79, y: 11.01), controlPoint2: CGPoint(x: 8.34, y: 3))
shape.addCurve(to: CGPoint(x: 27.25, y: 18.57), controlPoint1: CGPoint(x: 18.24, y: 13.01), controlPoint2: CGPoint(x: 27.25, y: 18.57))
shape.addCurve(to: CGPoint(x: 27.96, y: 19.01), controlPoint1: CGPoint(x: 27.55, y: 18.74), controlPoint2: CGPoint(x: 27.78, y: 18.88))
shape.addCurve(to: CGPoint(x: 28.47, y: 17.46), controlPoint1: CGPoint(x: 28.16, y: 18.51), controlPoint2: CGPoint(x: 28.33, y: 18))
shape.addCurve(to: CGPoint(x: 24.36, y: 0), controlPoint1: CGPoint(x: 30.03, y: 11.79), controlPoint2: CGPoint(x: 28.25, y: 5.34))
shape.addCurve(to: CGPoint(x: 36.48, y: 24.25), controlPoint1: CGPoint(x: 33.36, y: 5.45), controlPoint2: CGPoint(x: 38.7, y: 15.68))
shape.addCurve(to: CGPoint(x: 36.29, y: 24.93), controlPoint1: CGPoint(x: 36.42, y: 24.48), controlPoint2: CGPoint(x: 36.36, y: 24.7))
shape.addCurve(to: CGPoint(x: 36.37, y: 25.02), controlPoint1: CGPoint(x: 36.32, y: 24.96), controlPoint2: CGPoint(x: 36.34, y: 24.99))
shape.addCurve(to: CGPoint(x: 39.04, y: 35.37), controlPoint1: CGPoint(x: 40.82, y: 30.59), controlPoint2: CGPoint(x: 39.59, y: 36.48))
shape.addCurve(to: CGPoint(x: 29.89, y: 33.05), controlPoint1: CGPoint(x: 36.62, y: 30.65), controlPoint2: CGPoint(x: 32.16, y: 32.09))
shape.addLine(to: CGPoint(x: 29.89, y: 33.05))
shape.close()
return shape
}
Right, here's what I'm saying. Your path
method converts the UIBezierPath
to Path
right here:
Path(besier.cgPath)
I think you can probably do this when you're making the ShapeView
instead of waiting to do this during path
, so that the besier
property can be of type Path
instead of UIBezierPath
. And Path
is a Sendable
type.
Yes. I can just convert the UIBezierPath
to Path
in ShapeView.init
Or just start with Path
right off:
static var swiftLogo: Path {
var shape = Path()
shape.move(to: CGPoint(x: 29.89, y: 33.05))
shape.addCurve(to: CGPoint(x: 12.35, y: 33.25), control1: CGPoint(x: 25.22, y: 35.74), control2: CGPoint(x: 18.8, y: 36.02))
...
shape.closeSubpath()
return shape
}
Potential bonus point – no UIKit dependency (at least in this place).
The source of the UIBezierPath
is converted from SVG path with Website
So I just convert that to Path
at the end and work with Path
in my SwiftUI side.
Unless both UiBezierPath
and `Path‘ have identical API to construct the same path interchangeably?