图层蒙版的理解
CALayer有一个属性叫做mask可以解决这个问题。这个属性本身就是个CALayer类型,有和其他图层一样的绘制和布局属性。它类似于一个子图层,相对于父图层(即拥有该属性的图层)布局,但是它却不是一个普通的子图层。不同于那些绘制在父图层中的子图层,mask图层定义了父图层的部分可见区域。
mask图层的Color属性是无关紧要的,真正重要的是图层的轮廓。mask属性就像是一个饼干切割机,mask图层实心的部分会被保留下来,其他的则会被抛弃。
以上都摘自ios核心动画高级技巧,关键是对实心部分理解。所谓实心部分。就是非透明部分。透明部分会被挖空,不透明部分会保留。场景一个使用场景是镂空的渐变的loading图。
// Demo
#import "VSCustomView.h"
@implementation VSCustomView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupSubView];
}
return self;
}
- (void)setupSubView {
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.layer.bounds;
gradientLayer.startPoint = CGPointMake(0, 0);
gradientLayer.endPoint = CGPointMake(0, 1);
gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor, (__bridge id)[UIColor yellowColor].CGColor];
[self.layer addSublayer:gradientLayer];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.strokeColor = [UIColor blackColor].CGColor;
CGPoint center = CGPointMake(self.layer.bounds.size.width * 0.5, self.layer.bounds.size.height * 0.5);
shapeLayer.path = [UIBezierPath bezierPathWithArcCenter:center radius:(self.layer.bounds.size.width * 0.5 - 2) startAngle:0 endAngle:M_PI * 2 clockwise:YES].CGPath;
shapeLayer.lineWidth = 2;
[gradientLayer setMask:shapeLayer];
}
@end
效果
分析
shapeLayer作为mask Layer,使用clearColor镂空gradientLayer.strokeColor无论什么颜色都不会影响gradientLayer的颜色。但是不能是透明色。