iOS - Clipping union of two paths using UIBezierPath appendPath

core-graphics, graphics, ios, iphone, uibezierpath

Solution

You can add back the piece that gets knocked out by the intersection using `CGRectIntersection`

    CGContextSaveGState(context);

    CGRect rect1 = CGRectMake(centrePoint.x - 2.0f, 0.0f, 4.0f, self.sizeY);
    CGRect rect2 = CGRectMake(0.0f, centrePoint.y - 2.0f, self.sizeX, 4.0f);
    CGRect rect3 = CGRectIntersection(rect1, rect2);

    CGContextAddRect(context, rect1);
    CGContextAddRect(context, rect2);
    CGContextAddRect(context, rect3);

    CGRect boundingRect = CGContextGetClipBoundingBox(context);
    CGContextAddRect(context, boundingRect);
    CGContextEOClip(context);

        // draw the icon shape (clipped portion is removed)
    iconBezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(self.sizeX / 3.0f, self.sizeY / 2.25f, self.sizeX / 3.0f, self.sizeX / 3.0f)];

    [highlightColor setFill];
    [iconBezierPath fill];

    CGContextRestoreGState(context);

This satisfies the requirements of your question, but whether it entirely satisfies your needs depends on the nature of the "other overlapping paths".

Problem

I'm attempting the create a clipping path in the shape of a plus sign, so that subsequent paths that I draw into the same context have this portion removed. I create the clipping path using two rectangle paths overlaid on each other. This is what I'd like the final drawing to look like when I subsequently draw a circle: xXX| |XXx XXXX| |XXXX XXXXX| |XXXXX ——— ——— ——— ——— XXXXX| |XXXXX XXXX| |XXXX xXX| |XXx However, it actually looks like this: xXX| |XXx XXXX| |XXXX XXXXX| |XXXXX ——— XX——— ——— XX——— XXXXX| |XXXXX XXXX| |XXXX xXX| |XXx If I read this behaviour correctly, the intersection of the two rectangle paths is not forming part of the clipping mask. It seems (not surprisingly) that appendPath does not create a single unified path from my two rectangle paths in this case - I'm assuming that there is nothing I can do about this. Furthermore, Core Graphics doesn't seem to have any functions relating to path unions etc. Does anyone have any idea what I can do? I've included the relevant code snippet. Drawing the plus sign using one path isn't a solution, as I want to add other overlapping paths to my clipping mask. ``` CGContextSaveGState(context); // create clipping path UIBezierPath *clippingPath = [UIBezierPath bezierPath]; clippingPath = [UIBezierPath bezierPathWithRect:CGRectMake(centrePoint.x - 2.0f, 0.0f, 4.0f, self.sizeY)]; [clippingPath appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(0.0f, centrePoint.y - 2.0f, self.sizeX, 4.0f)]]; // use the clipping path to create a hole in the context CGContextAddPath(context, clippingPath.CGPath); CGRect boundingRect = CGContextGetClipBoundingBox(context); CGContextAddRect(context, boundingRect); CGContextEOClip(context); // draw the icon shape (clipped portion is removed) iconBezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(self.sizeX / 3.0f, self.sizeY / 2.25f, self.sizeX / 3.0f, self.sizeX / 3.0f)]; [highlightColor setFill]; [iconBezierPath fill]; CGContextRestoreGState(context); ```

Original source