CALayer有一个属性叫做mask
。
这个属性本身就是个CALayer类型,有和其他图层一样的绘制和布局属性。
它类似于一个子图层,相对于父图层(即拥有该属性的图层)布局,但是它却不是一个普通的子图层。
不同于那些绘制在父图层中的子图层,mask
图层定义了父图层的部分可见区域。
mask
图层的Color
属性是无关紧要的,真正重要的是图层的轮廓。mask
属性就像是一个饼干切割机,mask
图层实心的部分会被保留下来,其他的则会被抛弃
如果mask
图层比父图层要小,只有在mask
图层里面的内容才是它关心的,除此以外的一切都会被隐藏起来。
如下图
我们自己试试看
比如有两个Layer, 一个是红色的正方形,
一个小一点的绿色圆
如果把小一点的绿色圆当做红色正方形的maskLayer, 则最终只会在显示绿色圆范围内显示出原本红色正方形的内容
我们上代码
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //创建一个蓝色的Layer CALayer *foregroundLayer = [CALayer layer]; foregroundLayer.bounds = CGRectMake(0, 0, 100, 100); foregroundLayer.backgroundColor = [UIColor redColor].CGColor; //创建一个路径 UIBezierPath *apath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(20, 20, 60, 60)]; //创建maskLayer CAShapeLayer *maskLayer = [CAShapeLayer layer]; maskLayer.path = apath.CGPath; maskLayer.fillColor = [UIColor greenColor].CGColor; maskLayer.fillRule = kCAFillRuleEvenOdd; //设置位置 foregroundLayer.position = self.view.center; //设置mask foregroundLayer.mask = maskLayer; [self.view.layer addSublayer:foregroundLayer]; } @end
我们再可以给遮罩层添加动画, 实现更加绚丽的效果
比如中间中间小圆逐渐变大
#import "ViewController.h" static CGFloat num; @interface ViewController () @property (nonatomic, strong) CAShapeLayer *circle; @property (nonatomic, strong) CADisplayLink *link; @end @implementation ViewController @synthesize circle; - (void)viewDidLoad { [super viewDidLoad]; //创建一个CAShape CALayer *bgLayer = [CALayer layer]; //设置大小颜色和位置 bgLayer.bounds = CGRectMake(0, 0, 200, 200); bgLayer.backgroundColor = [UIColor redColor].CGColor; bgLayer.position = self.view.center; //创建一个CAShapeLayer作为MaskLayer circle = [CAShapeLayer layer]; //设置路径 circle.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:20 startAngle:0 endAngle:2 * M_PI clockwise:YES].CGPath; circle.lineWidth = 5; circle.fillColor = [UIColor greenColor].CGColor; circle.fillRule = kCAFillRuleEvenOdd; //设置maskLayer bgLayer.mask = circle; [self.view.layer addSublayer:bgLayer]; //添加计时器 self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(action)]; [self.link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; } - (void)action { num ++; circle.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:20 + num startAngle:0 endAngle:2 * M_PI clockwise:YES].CGPath; if (num > 1000) { [self.link invalidate]; } }