-(void)testHoleRect{
UIView* aView = [[UIView alloc] initWithFrame:CGRectMake(100, 80, 100, 100)];
[self.view addSubview:aView];
//用来标识layer的绘图是否正确
aView.layer.borderWidth = 1.0;
aView.layer.borderColor = [UIColor blackColor].CGColor;
CAShapeLayer* cropLayer = [[CAShapeLayer alloc] init];
[aView.layer addSublayer:cropLayer];
CGMutablePathRef path = CGPathCreateMutable();
CGRect cropRect = CGRectMake(20, 30, 60, 40);
CGPathAddRect(path, nil, aView.bounds);
CGPathAddRect(path, nil, cropRect);
//重点
[cropLayer setFillRule:kCAFillRuleEvenOdd];
[cropLayer setPath:path];
[cropLayer setFillColor:[[UIColor redColor] CGColor]];
}
效果:
关键点:
kCAFillRuleEvenOdd.
可参考下面的文章,说的很清楚了。
http://blog.csdn.net/cuixiping/article/details/7848369
图形填充规则通过fill-rule属性来指定。
-
‘fill-rule’
-
有效值: nonzero | evenodd | inherit 默认值: nonzero 应用于: shape形状类元素 和 文字内容类元素 可继承: 是 比例: 无 媒体: 可见 动画可用: 是
‘fill-rule’ 属性用于指定使用哪一种算法去判断画布上的某区域是否属于该图形“内部” (内部区域将被填充)。对一个简单的无交叉的路径,哪块区域是“内部” 是很直观清除的。但是,对一个复杂的路径,比如自相交或者一个子路径包围另一个子路径,“内部”的理解就不那么明确了。
‘fill-rule’ 属性提供两种选项用于指定如何判断图形的“内部”:
-
nonzero
- 字面意思是“非零”。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点情况。从0开始计数, 路径从左向右穿过射线 则计数加1, 从右向左穿过射线 则计数减1。得出计数结果后,如果结果是0,则认为点在图形外部,否则认为在内部。下图演示了 nonzero 规则 :
- 注:这种方式和path的方向是相关的,第三个图和第二个图和的区别在于最里边的圆形path的方向不一样。结果第三张图的最里面部分就不属于图了。
- evenodd
-
字面意思是“奇偶”。
按该规则,
要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的
交点
的数量。如果结果是奇数则认为点在内部,是偶数则认为点在外部。
下图演示了
evenodd
规则
: