Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I combine UIBezierPath drawings?

I'm trying to combine several UIBezierPath drawings.

I have different types of drawings I can make (line, cubic bezier, quadratic beziers), and each of these can be filled or unfilled. I'm selecting the drawing type randomly, and my goal is to make 3 different drawings which are connected at a point.

So where the first, say, line drawing ends, the second path - maybe a cubic bezier — begins. Where that ends, a third, maybe a filled line drawing begins.

I've got a square UIView that I'm trying to draw this in, and each path should have its own part of the UIView: the first 1/3rd, the second and the third.

Would I be able to create this with one UIBezierPath object, or do I need to create 3 different ones? How to make them end and start at the same point? Is there a way to do this with subpaths?

like image 972
pikovayadama Avatar asked May 11 '13 04:05

pikovayadama


3 Answers

UIBezierPath has its instance methods like (DOC)

  • -addLineToPoint:
  • -addArcWithCenter:radius:startAngle:endAngle:clockwise:
  • -addCurveToPoint:controlPoint1:controlPoint2:
  • -addQuadCurveToPoint:controlPoint:
  • -appendPath:

You can combine paths one by one. When you've done, use -closePath to close the path.

Feel free to take a look at my open sourced lib which called UIBezierPath-Symbol. ;)


And if you want more customise path drawing, I recommend CGMutablePath. You can create each path as complex as you want (you can combine simple paths by CGPathAdd... methods). Finally, use CGPathAddPath() to combine them together.

void CGPathAddPath (  
  CGMutablePathRef path1,     // The mutable path to change.
  const CGAffineTransform *m, // A pointer to an affine transformation matrix, or NULL if no transformation is needed. If > specified, Quartz applies the transformation to path2 before it is added to path1.
  CGPathRef path2             // The path to add.
);
like image 113
Kjuly Avatar answered Nov 19 '22 23:11

Kjuly


You can combine paths like this:

UIBezierPath *endPath = [UIBezierPath bezierPath];
[endPath appendPath:leftLine];
[endPath appendPath:rightLine];
[endPath appendPath:midLine];

bezier path arrow example

like image 20
David Avatar answered Nov 19 '22 23:11

David


A UIBezierPath is just a wrapper for a CGPath, which itself is just a set of instructions for drawing (by stroke or fill, or both). That drawing can take place anywhere. In other words, a UIBezierPath is just a tool for drawing; the important thing is the drawing itself. Given a graphics context (which might be a UIView, a UIImage, a CALayer, whatever), you can do as much drawing as you like in succession - say, a line, then a cubic bezier, then a filled line drawing. But how you perform those drawing bits is totally up to you. You shouldn't really care whether you do it with three UIBezierPaths, one UIBezierPath, multiple paths, one path, subpaths, whatever (or even by copying other drawings into this one) - the final effect is all that matters, i.e. the accumulated drawing ultimately done in this graphics context.

Your question is like asking, "Should I draw this circle with my right hand or my left hand, and should I draw it counter-clockwise or clockwise?" It doesn't matter. Once it's done, what will have been drawn is a circle; that is what's important.

like image 3
matt Avatar answered Nov 19 '22 22:11

matt