Search code examples
iosswiftuibezierpath

Is there a UIBezierPath equivalent of CGPath's `addArc(tangent1End:tangent2End:radius:transform:)`?


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.


Solution

  • 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.