Constructing custom variations of rounded rectangles is fussy business. The Swift V 5.1 answer in this thread:
Swift: UIBezierPath Stroke Animation from Center
Describes out to draw a rounded rectangle starting from the top center, so you can animate stroking it starting from that point.
It uses the UIBezierPath method addArc(withCenter:radius:startAngle:endAngle:clockwise:)
to draw the corner arcs of the rounded rectangle.
Getting the code right to draw the connected series of line segments and quarter arcs requires quite a bit of care, plus some knowledge of trig to figure out the angles of the different arcs for each quadrant.
CGPath has a variation on addArc, addArc(tangent1End:tangent2End:radius:transform:)
, that works differently. It takes "tangent end" points that define the arc in a way that's less fussy to set up (once you figure out how it works.)
I can't find an equivalent method for UIBezierPath. Am I missing something? I guess the answer is to create a CGPath
(or rather, CGMutablePath
using calls to addArc(tangent1End:tangent2End:radius:transform:)
and then use the UIBezierPath initializer that takes a CGPath, but that is an added step that makes the code a little bit more confusing.
It looks like there is no UIBezierPath
equivalent to the CGPath
method addArc(tangent1End:tangent2End:radius:transform:)
.
I guess the answer is to just use CGPath
when you want to add arcs in the form addArc(tangent1End:tangent2End:radius:transform:)
, and then convert the result to a UIBezierPath
using the UIBezierPath.init(cgPath:)
initializer.
At first I was thinking I could write an extension of UIBezierPath
that would add a addArc(tangent1End:tangent2End:radius:transform:)
method to UIBezierPath
, but that would get very messy, since addArc(tangent1End:tangent2End:radius:transform:)
uses the current pen position in the active path to figure out the first tangent line.