iOS 利用CAShapeLayer的FillRule屬性生成一個空心遮罩的layer

1.空心矩形框:
通過設置填充規則為kCAFillRuleEvenOdd,繪制兩個Rect的非交集

  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();
  // 空心矩形的rect
  CGRect cropRect = CGRectMake(20, 30, 60, 40);
  // 繪制rect
  CGPathAddRect(path, nil, aView.bounds);
  CGPathAddRect(path, nil, cropRect);
  // 設置填充規則(重點)
  [cropLayer setFillRule:kCAFillRuleEvenOdd];
  // 關聯繪制的path
  [cropLayer setPath:path];
  // 設置填充的顏色
  [cropLayer setFillColor:[[UIColor redColor] CGColor]];

效果圖 :

1.png

2.空心圓:
通過設置填充規則為kCAFillRuleEvenOdd,繪制Rect和Arc的非交集

     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;
           //重點
     pShapeLayer.fillRule = kCAFillRuleEvenOdd;

效果圖:


2.png

重點:理解填充規則 fillRule

/* The fill rule used when filling the path. Options are `non-zero' and
 * `even-odd'. Defaults to `non-zero'. */
@property(copy) NSString *fillRule; ```
     
屬性用于指定使用哪一種算法去判斷畫布上的某區域是否屬于該圖形“內部” (內部區域將被填充)。對一個簡單的無交叉的路徑,哪塊區域是“內部” 是很直觀清除的。但是,對一個復雜的路徑,比如自相交或者一個子路徑包圍另一個子路徑,“內部”的理解就不那么明確了。

`kCAFillRuleNonZero`
     字面意思是“非零”。按該規則,要判斷一個點是否在圖形內,從該點作任意方向的一條射線,然后檢測射線與圖形路徑的交點情況。從0開始計數,路徑從左向右穿過射線則計數加1,從右向左穿過射線則計數減1。得出計數結果后,如果結果是0,則認為點在圖形外部,否則認為在內部。下圖演示了kCAFillRuleNonZero規則:
![3.png](http://upload-images.jianshu.io/upload_images/833634-f1b5b4a0052db40e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

`kCAFillRuleEvenOdd`
     字面意思是“奇偶”。按該規則,要判斷一個點是否在圖形內,從該點作任意方向的一條射線,然后檢測射線與圖形路徑的交點的數量。如果結果是奇數則認為點在內部,是偶數則認為點在外部。下圖演示了kCAFillRuleEvenOdd 規則:
![4.png](http://upload-images.jianshu.io/upload_images/833634-f522192d09f24ff0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

原文鏈接:[http://keepmovingxin.com/archives/21](http://keepmovingxin.com/archives/21)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容