Core Graphics, how to draw a Rectangle with an ell

2019-02-15 12:19发布

I am trying to draw a 320x480 rectangle that is hollowed by a ellipse. Imagine drawing a filled rectangle, over the rectangle an filled ellipse, and remove the ellipse from the rectangle, leaving a transparent hole.

- (void)drawRect:(CGRect)rect
{
        // Drawing code.
    CGContextRef context = UIGraphicsGetCurrentContext();
    // Set color to red
    CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0);
    // Add rectange
    CGContextAddRect(context, rect);
    // Fill rectange
    CGContextFillRect(context, rect);

    // Create a elipse to be removed from rectange

    CGPathRef circlePath = CGPathCreateMutable();       
    CGPathAddEllipseInRect(circlePath , NULL , elipseRect);

    CGContextAddPath(context, circlePath);  
    CGContextSetRGBFillColor(context, 1.0, 1.0, 0.0, 1.0);
    CGContextFillPath(context);

    // clip elipse... (DO NOT WORK)
    CGContextEOClip(context);
}

When I am trying to remove the elipse from the rectange, it does not work.

Anybody has a solution?

1条回答
聊天终结者
2楼-- · 2019-02-15 12:59

This is off the top of my head, but...

CGPathRef cutoutRect = CGPathCreateMutable();       
CGPathAddRect(cutoutRect, NULL, rect);
CGPathAddEllipseInRect(cutoutRect, NULL, ellipseRect);

CGContextAddPath(context, cutoutRect);  
CGContextSetRGBFillColor(context, 1.0, 1.0, 0.0, 1.0);
CGContextFillPath(context);

You may actually need to use CGContextEOFillPath, I can never keep them straight. The CGContextClip-type functions should be used before drawing rather than after, but they're probably not necessary in this case.

That said, you shouldn't be doing this in a -drawRect: implementation, but the path should be set on a CAShapeLayer which is a sublayer of this view, or its only layer, or, indeed, a layer which is used instead of this view if possible.

Also note that the rectangle passed into drawRect: may be only part of the whole view, so your code will have some pretty weird results as-is. Did you mean self.bounds?

查看更多
登录 后发表回答