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: