问题
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);
回答1:
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".
来源:https://stackoverflow.com/questions/15551384/ios-clipping-union-of-two-paths-using-uibezierpath-appendpath