知 识 点 / 超 人
为什么要单独写一篇关于mask的呢,因为本人最近在写一篇关于界面渲染的文章,其中详细的讲解了CALayer。而mask是CALayer中一个比较特殊的存在。所以这里单独写一篇mask详细说明下
mask(遮罩层)
一个CALayer中如果存在多个子CALayer,与一个UIView中存在多个子View是一样的。但CALayer中还有一个特殊的存在,mask(遮罩层),mask是CALayer的一个属性,其本身也是CALayer,添加mask也是添加一个子CALayer。但是呈现方式与加一个子CALayer不同。
- 首先是一个未加mask的的单纯UIView
FView *fView = [FView new];
[self.view addSubview:fView];
fView.frame = CGRectMake(0, 420, 75, 75);
fView.backgroundColor = [UIColor greenColor];
fView.layer.borderColor = [UIColor orangeColor].CGColor;
fView.layer.borderWidth = 2;
- 然后我们给这个UIView加上一个mask
FView *fView = [FView new];
[self.view addSubview:fView];
fView.frame = CGRectMake(0, 420, 75, 75);
fView.backgroundColor = [UIColor greenColor];
fView.layer.borderColor = [UIColor orangeColor].CGColor;
fView.layer.borderWidth = 2;
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(10, 10, 55, 55);
fView.layer.mask = layer;
加上mask后整个绿色界面完全消失了,并且我们的mask大小只设置了 55,绿色界面大小是75,绿色界面以内mask以外的区域也没显示.而是整个UIView都消失了。
- 接着我们先给mask设置一个backgroundColor
layer.backgroundColor = [UIColor redColor].CGColor;
界面变小了,并且没有对齐屏幕左边界。这是因为我们设置mask的frame为CGRectMake(10, 10, 55, 55),mask层只会显示原本CALayer在mask中的区域。但是我们设置的backgroundColor为red。界面还是显示的绿色。
- 然后我们给mask的backgroundColor透明度设置为0
layer.backgroundColor = [UIColor colorWithRed:255 green:0 blue:0 alpha:0].CGColor;
结果界面上还是没有显示出UIView。不论Color的颜色值如何修改都不会显示。从这里可以看出,mask的backgroundColor对mask和原本CALayer并没有影响,有影响的是透明度。但是为什么透明度明明为0,结果界面不显示呢,透明度为0,mask层不应该是透明的吗,应该可以完整显示原本CALayer界面吧。这就是mask的特殊之处
- 当我们把透明度改为1
layer.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1].CGColor;
绿色的界面又出现了。
-
然后我们把backgroundColor取掉,给mask添加一个contents层。
添加一个图片
可以看出,图片中方块内部是透明的,图片只有一个边框是非透明区域。
CALayer *layer = [CALayer layer];
layer.contents = (__bridge id)[UIImage imageNamed:@"ce_02"].CGImage;
layer.contentsGravity = kCAGravityResizeAspect;
fView.layer.mask = layer;
界面只显示了一个与图片一样的边框,而且边框颜色居然是绿色,图片明明是灰色的。其实从这一点就可以看出,mask的颜色对mask和底层的CALayer并没有任何影响,但为什么只显示一个边框呢,因为mask的Alpha值决定了mask中contents层和background层的显示量。完全不透明或部分不透明时是允许底层原CALayer的像素内容显示的,但完全透明的时候是不允许底层原CALayer像素内容显示的。
- 最后我们把backgroundColor的Alpha设置为0,并添加一个contents层图片。
CALayer *layer = [CALayer layer];
layer.contents = (__bridge id)[UIImage imageNamed:@"ce_02"].CGImage;
layer.contentsGravity = kCAGravityResizeAspect;
layer.backgroundColor = [UIColor colorWithRed:255 green:0 blue:0 alpha:0].CGColor;
layer.frame = CGRectMake(10, 10, 55, 55);
fView.layer.mask = layer;
alpha都设置为0了,为什么会显示边框呢?这是因为CALayer分为3层,contents层、backgroundColor层还有border层。alpha只会影响backgroundColor层。控制整个mask透明度的是opacity属性而不是alpha
mask总结:
mask中不论contents层、backgroundColor层还有border层,颜色对mask和底层的CALayer没有任何影响。 影响mask的只有透明度,而opacity是控制整个mask的,alpha是控制backgroundColor。(只修改backgroundColor层的情况下)
当alpha为0时,整个mask与底层CALayer都不会显示。
当alpha为1时,只有mask区域以内非透明区域会显示该区域对应底层CALayer的像素值。