Mask属性介绍
Posted TF_guo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mask属性介绍相关的知识,希望对你有一定的参考价值。
Mask属性介绍
Mask平时用的最多的是masksToBounds 吧. 其实除此以外Mask使用场景很多,看完之后你会发现好真是好用的不要不要的...
先来了解下Mask属性到底是什么?
Mask 英文解释是蒙板/面罩,平时我们称为蒙层. 在苹果官方文档里如下图,意思是Mask是一个可选的Layer,它可以是根据透明度来掩盖Layer的内容.
这么一说好像...还是不晓得有什么卵用...
那再看下面这个说明,意思是Layer的透明度决定了Layer内容是否可以显示,非透明的内容和背景可以显示,透明的则无法显示.
Mask 实例使用
实例1:渐变进度条
先看"脸" 再谈"内涵"
整个动画效果主要可以分成4步骤:
1.创建一个CALayer 做为背景色进度条
1 CALayer *bgLayer = [CALayer layer]; 2 3 bgLayer.frame = CGRectMake(kNumberMarkWidth / 2, self.numberMarkView.bottom + 10.f, self.width - kNumberMarkWidth / 2, kProcessHeight); 4 5 bgLayer.backgroundColor = [UIColor colorWithHex:0xF5F5F5].CGColor; 6 7 bgLayer.masksToBounds = YES; 8 9 bgLayer.cornerRadius = kProcessHeight / 2; 10 11 [self.layer addSublayer:bgLayer];
2.创建一个CAGradientLayer 渐变效果的Layer
1 self.gradientLayer = [CAGradientLayer layer]; 2 self.gradientLayer.frame = bgLayer.frame; 3 self.gradientLayer.masksToBounds = YES; 4 self.gradientLayer.cornerRadius = kProcessHeight / 2; 5 // 设置渐变颜色数组 6 [self.gradientLayer setColors:[NSArray arrayWithObjects: 7 (id)[[UIColor colorWithHex:0xFF6347] CGColor], 8 [(id)[UIColor colorWithHex:0xFFEC8B] CGColor], 9 (id)[[UIColor colorWithHex:0xEEEE00] CGColor], 10 (id)[[UIColor colorWithHex:0x7FFF00] CGColor], 11 nil]]; 12 // 设置渐变位置数组 13 [self.gradientLayer setLocations:@[@0.3, @0.5, @0.7, @1]]; 14 // 设置渐变开始和结束位置 15 [self.gradientLayer setStartPoint:CGPointMake(0, 0)]; 16 [self.gradientLayer setEndPoint:CGPointMake(1, 0)];
3.创建一个Mask Layer,并设置为CAGradientLayer渐变层的Mask. 然后通过设置maskLayer 宽度来控制进度了. 是不是很简单,不过好像没有感觉不出Mask的强大之处...
1 self.maskLayer = [CALayer layer]; 2 self.maskLayer.frame = CGRectMake(0, 0, (self.width - kNumberMarkWidth / 2) * self.percent / 100.f, kProcessHeight); 3 [self.gradientLayer setMask:self.maskLayer];
1 - (void)circleAnimation // 进度条动画 2 3 [CATransaction begin]; 4 [CATransaction setDisableActions:NO]; 5 [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; 6 [CATransaction setAnimationDuration:kAnimationTime]; 7 self.maskLayer.frame = CGRectMake(0, 0, (self.width - kNumberMarkWidth / 2) * _percent / 100.f, kProcessHeight); 8 [CATransaction commit]; 9
4.文字渐变,这个就能看出Mask 的特点了.
先创建一个Label展示分数,再同第2步创建一个一样的渐变CAGradientLayer.将Label的关联图层设置为渐变CAGradientLayer 的Mask, 这样就OK了.
上面有说过Mask属性特点是内容非透明则可以显示,透明则隐藏.
实例中,Label做为渐变层的Mask, Label中文字部分是非透明的,其他是透明的.那么文字和文字背景(这里就是渐变层)可以显示.大概就像镂空文字部分,然后显示出底下的渐变层.
最后只要移动Label 的位置就能看到我们所要的效果文字颜色渐变. 下左图设置了Mask , 下右图未设置Mask.
1 - (void)setNUmberMarkLayer // 提示文字设置渐变色 2 3 CAGradientLayer *numberGradientLayer = [CAGradientLayer layer]; 4 numberGradientLayer.frame = CGRectMake(0, kTopSpaces, self.width, kNumberMarkHeight); 5 [numberGradientLayer setColors:self.colorArray]; 6 [numberGradientLayer setLocations:self.colorLocationArray]; 7 [numberGradientLayer setStartPoint:CGPointMake(0, 0)]; 8 [numberGradientLayer setEndPoint:CGPointMake(1, 0)]; 9 [self.layer addSublayer:numberGradientLayer]; 10 [numberGradientLayer setMask:self.numberMark.layer]; 11 self.numberMark.frame = numberGradientLayer.bounds; 12
源码可以进github查看: https://github.com/xl20071926/LXGradientProcessView
另外还有类似的仿照芝麻信用,用Mask和CAShaperLayer 做的,有兴趣的也可以看下:https://github.com/xl20071926/LXCircleAnimationView
实例2:镂空效果
新手引导大多数app都会有这个功能,然而据了解蛮多就是直接贴张图片上面就搞定了.
额,这样做确实简单,可是这样好Low而且做出来的效果不好,那我们来用逼格高点的镂空方式实现:
先来一个简单的效果图:
实现起来也很简单,主要分3个步骤:
1.创建一个镂空的路径:
UIBezierPath 有个原生的方法- (void)appendPath:(UIBezierPath *)bezierPath, 这个方法作用是俩个路径有叠加的部分则会镂空.
这个方法实现原理应该是path的FillRule 默认是FillRuleEvenOdd(CALayer 有一个fillRule属性的规则就有kCAFillRuleEvenOdd), 而EvenOdd 是一个奇偶规则,奇数则显示,偶数则不显示.叠加则是偶数故不显示.
2.创建CAShapeLayer 将镂空path赋值给shapeLayer
3.将shapeLayer 设置为背景视图的Mask
1 UIView *backgroundView = [[UIView alloc] init]; 2 backgroundView.frame = self.view.bounds; 3 backgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7]; 4 [self.view addSubview:backgroundView]; 5 // 创建一个全屏大的path 6 UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.view.bounds]; 7 // 创建一个圆形path 8 UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.view.center.x, self.view.center.y - 25) 9 radius:50 10 startAngle:0 11 endAngle:2 * M_PI 12 clockwise:NO]; 13 [path appendPath:circlePath]; 14 15 CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 16 shapeLayer.path = path.CGPath; 17 backgroundView.layer.mask = shapeLayer;
顺便提下,在实际开发中可能遇到这种需求,当tableView 滑动到某个位置的时候才显示新手引导.
这时候就需要将tableView上的坐标转化为相对于屏幕的坐标. 可用原生的方法:
- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;
- (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;
好了,介绍完毕.
以上是关于Mask属性介绍的主要内容,如果未能解决你的问题,请参考以下文章
深度学习和目标检测系列教程 17-300: 3 个类别面罩检测类别数据集训练yolov5s模型