I'm try to dynamically create puzzle piece, and it looks like this:
I want to fill this shape with some color so it will looks like this:
so I can use it for masking some image.
PROBLEM:
I creating this shape with 4 UIBezierPath, then convert it to 1 path using appendPath
.
I want to fill this path but when I use fill
I got this:
Do you have any ideas how I can fill same shapes?

- 1,434
- 5
- 22
- 41
3 Answers
After some time I found a reason why I got these results.
If you want to create some path for filling you should not use moveToPoint
method, instead you should just once set first point using moveToPoint
and then draw all lines with addLineToPoint
, addCurveToPoint
, etc.
After you complete draw your path do not forget send closePath
message.
Before I knew this, I drew every side of puzzle piece using different UIBezierPath instances and for every path I set first point using moveToPoint
.

- 1,434
- 5
- 22
- 41
-
I'm running into the same problem, but I don't think your solution will work. Using your puzzle piece as an analogy, the right and bottom edges are created using cubic bezier curves that are essentially identical, with the second one simply being a CGAffineTransform of the other. Even without using the moveToPoint on the second curve, the transform appears to keep the two curves from joining, so the scope of the fill is just the curve defining each side. If someone has a solution to this where the transform can still be used, please share. – Victor Engel Apr 27 '13 at 22:48
-
@Victor Engel, my solution is working and I use it in my application. Why you talking about CGAffineTransform? I am not using it to draw puzzle piece lines. All bezier lines was drawn using coordinates which was calculated for each bezier curve. – Artem Shmatkov Apr 28 '13 at 05:48
-
I wasn't trying to suggest that was your issue. I was using your illustration to illustrate a complication. You many not use a transform, but a transform COULD be used to transform one to the other without having to figure out the other coordinates. I think my solution will be to apply the transform to CGPoints so that the paths don't need to be transformed. Then I can add them all in one path. – Victor Engel Apr 28 '13 at 05:53
-
I believe `closePath` is not needed, it's implicitly called. – ninjaneer Jul 26 '14 at 09:25
-
@zakhej Hey mate! Thanks for sharing, you save me couple of hours :D – RomOne Aug 10 '16 at 09:45
If you have a path defining your puzzle piece, it'll be easier to manipulate it if you turn it into a CAShapeLayer
:
CAShapeLayer *myShapeLayer = [CAShapeLayer layer];
myShapeLayer.path = myBezierCurves.CGPath;
myShapeLayer.fillColor = [[UIColor blackColor] CGColor];
myShapeLayer.strokeColor = [[UIColor redColor] CGColor];
myShapeLayer.lineWidth = 2;

- 16,003
- 15
- 87
- 139
-
Thank you for advice, I got this: [not filled image](http://i.imgur.com/6ceJj.png) And it is not filled... – Artem Shmatkov Sep 05 '12 at 10:58
-
Try this: as intention to make one UIbenzierPath with all combined points
Add below method in .m file.
void MyCGPathApplierFunc (void *info, const CGPathElement *element) {
UIBezierPath *drawingPath = (UIBezierPath *)info;
CGPoint *points = element->points;
CGPathElementType type = element->type;
switch(type) {
case kCGPathElementMoveToPoint: // contains 1 point
[drawingPath moveToPoint:[[NSValue valueWithCGPoint:points[0]] CGPointValue]];
break;
case kCGPathElementAddLineToPoint: // contains 1 point
[drawingPath addLineToPoint:[[NSValue valueWithCGPoint:points[0]] CGPointValue]];
break;
case kCGPathElementAddQuadCurveToPoint: // contains 1 point
[drawingPath addQuadCurveToPoint:[[NSValue valueWithCGPoint:points[0]] CGPointValue]];
break;
case kCGPathElementAddCurveToPoint: // contains 1 point
[drawingPath addCurveToPoint:[[NSValue valueWithCGPoint:points[0]] CGPointValue]];
break;
case kCGPathElementCloseSubpath: // contains no point
break;
}
}
Add UIBezierPath *combinedpath; in .h file U can use method like:
combinedpath = [[UIBezierPath alloc]init];
CGPathApply(appendedBenzierPath.CGPath, (void *)combinedpath, MyCGPathApplierFunc);
[self setNeedsDisplay];
Now fill in these combinedpath
- (void)drawRect:(CGRect)rect
{
[[UIColor blackColor] setStroke];
[combinedpath strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
[combinedpath fill];
}

- 38,095
- 11
- 81
- 132
-
XCode says that `"Instance method '-addQuadCurveToPoint' not found"`, same as addCurveToPoint at "MyCGPathApplierFunc" function. And so I have error at runtime `"-[UIBezierPath addCurveToPoint:]: unrecognized selector sent to instance"` – Artem Shmatkov Sep 05 '12 at 11:04
-
-
-
When I implement `drawRect` method, I see only black screen. And There are nothing drawn. – Artem Shmatkov Sep 05 '12 at 11:35
-