iOS uses the FillRule property of CAShapeLayer to generate a hollow masked Layer

1. Hollow rectangular box:
Draw the non-intersection of two Rects by setting the filling rule to kCAFillRuleEvenOdd
UIView aView = [[UIView alloc] initWithFrame:CGRectMake(100,80, 100, 100)];
[self.view addSubview:aView];
//Used to identify whether the drawing of the layer is correct
aView.layer.borderWidth = 1.0;
aView.layer.borderColor = [UIColor blackColor].CGColor;
CAShapeLayer cropLayer = [[CAShapeLayer alloc] init];
[aView.layer addSublayer:cropLayer];
// create a drawing path
CGMutablePathRef path =CGPathCreateMutable();
// The rect of the hollow rectangle
CGRect cropRect = CGRectMake(20, 30, 60, 40);
// draw rect
CGPathAddRect(path, nil, aView.bounds);
CGPathAddRect(path, nil, cropRect);
// Set the filling rules (emphasis)
[cropLayer setFillRule:kCAFillRuleEvenOdd];
// Associate the drawn path
[cropLayer setPath:path];
// set the fill color
[cropLayer setFillColor:[[UIColor redColor] CGColor]];


Rendering:

2. Hollow circle:
Draw the non-intersection of Rect and Arc by setting the filling rule to kCAFillRuleEvenOdd
CAShapeLayer *pShapeLayer = [CAShapeLayer layer];
 pShapeLayer.fillColor = [UIColor blackColor].CGColor;[self.overlayView.layer addSublayer:pShapeLayer];UIBezierPath *pPath = [UIBezierPath bezierPathWithArcCenter:self.overlayView.center radius:SCALE_FRAME_Y/2 startAngle:0.0 endAngle:M_PI*2 clockwise:YES];
 pShapeLayer.path = pPath.CGPath;

 UIBezierPath *pOtherPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
 pShapeLayer.path = pOtherPath.CGPath;

 [pOtherPath appendPath:pPath];
 pShapeLayer.path = pOtherPath.CGPath;
       // point
 pShapeLayer.fillRule = kCAFillRuleEvenOdd;

效果图:

/* The fill rule used when filling the path. Options are `non-zero' and
  • even-odd'. Defaults to
  • non-zero'. /@property(copy) NSString fillRule; The property is used to specify which algorithm to use to determine whether an area on the canvas is "inside" (the inner area will be filled) of the graphic. For a simple non-intersecting path, it is straightforward to clear which area is "inside". However, for a complex path, such as a self-intersection or one sub-path enclosing another sub-path, the understanding of "inside" is less clear.

kCAFillRuleNonZero

literally means "non-zero". According to this rule, to judge whether a point is in the graph, draw a ray from this point in any direction, and then detect the intersection of the ray and the graph path. The count starts from 0, and the count increases by 1 when the path crosses the ray from left to right, and decreases by 1 when the path crosses the ray from right to left. After the count result is obtained, if the result is 0, the point is considered to be outside the graph, otherwise it is considered to be inside. The following figure demonstrates the kCAFillRuleNonZero rule:

kCAFillRuleEvenOdd
literally means "odd and even". According to this rule, to judge whether a point is in the graph, draw a ray from this point in any direction, and then detect the number of intersections between the ray and the graph path. If the result is odd, the point is considered to be inside, and if the result is even, the point is considered to be outside. The following figure demonstrates the kCAFillRuleEvenOdd rule:

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326413297&siteId=291194637