这里 layer 有几个属性 cropAreaLeft、cropAreaRight、cropAreaTop、cropAreaBottom,从命名上可以看出这几个属性定义了这个 layer 上绘制的白边框裁剪区域的坐标信息。还暴露了一个方法用于配置这四个属性。
然后在 CAShapeLayer 内部,重点在于复写 drawInContext 方法,这个方法负责直接在图层上绘图,复写的方法主要做的事情是根据上面四个属性 cropAreaLeft、cropAreaRight、cropAreaTop、cropAreaBottom 绘制出封闭的四条线,这样就能表示裁剪区域的边界了。
要注意的是 drawInContext 方法不能手动显示调用,必须通过调用 setNeedsDisplay 或者 setNeedsDisplayInRect 让系统自动调该方法。
在裁剪页面里,我们放置了一个 cropView,然后将自定义的 CAShaplayer 加入到这个 view 上
self.cropView.layer.sublayers = nil;
YasicClipAreaLayer * layer = [[YasicClipAreaLayer alloc] init];
CGRect cropframe = CGRectMake(self.cropAreaX, self.cropAreaY, self.cropAreaWidth, self.cropAreaHeight);
UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:self.cropView.frame cornerRadius:0];
UIBezierPath * cropPath = [UIBezierPath bezierPathWithRect:cropframe];
[path appendPath:cropPath];
layer.path = path.CGPath;
layer.fillRule = kCAFillRuleEvenOdd;
layer.fillColor = [[UIColor blackColor] CGColor];
layer.opacity = 0.5;
layer.frame = self.cropView.bounds;
[layer setCropAreaLeft:self.cropAreaX CropAreaTop:self.cropAreaY CropAreaRight:self.cropAreaX + self.cropAreaWidth CropAreaBottom:self.cropAreaY + self.cropAreaHeight];
[self.cropView.layer addSublayer:layer];
[self.view bringSubviewToFront:self.cropView];
这里主要是为了用自定义的 CAShapelayer 产生出空心遮罩的效果,从而出现中心的裁剪区域高亮而四周非裁剪区域有蒙层的效果,示意图如下

所以首先确定了 cashapelayer 的大小为 cropview 的大小,生成一个对应的 UIBezierPath,然后根据裁剪区域的大小(由 self.cropAreaX, self.cropAreaY, self.cropAreaWidth, self.cropAreaHeight 确定)生成空心遮罩的内圈 UIBezierPath,
CGRect cropframe = CGRectMake(self.cropAreaX, self.cropAreaY, self.cropAreaWidth, self.cropAreaHeight);
UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:self.cropView.frame cornerRadius:0];
UIBezierPath * cropPath = [UIBezierPath bezierPathWithRect:cropframe];
[path appendPath:cropPath];
layer.path = path.CGPath;
然后将这个 path 配置给 CAShapeLayer,并将 CAShapeLayer 的 fillRule 配置为 kCAFillRuleEvenOdd
layer.fillRule = kCAFillRuleEvenOdd;
layer.fillColor = [[UIColor blackColor] CGColor];
layer.opacity = 0.5;
layer.frame = self.cropView.bounds;










