CALayer有一個(gè)屬性叫做mask(對(duì)應(yīng)UIView中maskView屬性,下文說(shuō)的maskView和mask是一個(gè)東西),mask圖層定義了父圖層的部分可見(jiàn)區(qū)域,功能類似于PS 中的圖層蒙版。
mask圖層的Color屬性是無(wú)關(guān)緊要的,真正重要的是圖層的輪廓。mask屬性就像是一個(gè)餅干切割機(jī),mask圖層實(shí)心的部分會(huì)被保留下來(lái),其他的則會(huì)被拋棄。(如圖1.1)。
也可以這樣理解,maskView將每個(gè)point的alpha賦值給View的重疊部分相對(duì)應(yīng)的point,這樣view的重疊每個(gè)point都有個(gè)alpha值了,view重疊部分就可能顯示多種透明色。
就如圖1.1 而言,由于maskView顏色的alpha為1.0,那么與view重疊部分的alpha也應(yīng)該為1.0(即重疊部分沒(méi)變化),與mask顏色沒(méi)關(guān)系。

還是云里霧里的也沒(méi)關(guān)系。您可以下載demo對(duì)照學(xué)習(xí),注釋非常詳細(xì),一看就懂。
demo中前三個(gè)例子可有幫助更深刻的體會(huì)mask屬性的基本原理。
CALayer蒙板圖層真正厲害的地方在于蒙板圖不局限于靜態(tài)圖。任何有圖層構(gòu)成的都可以作為mask屬性,這意味著你的蒙板可以通過(guò)代碼甚至是動(dòng)畫實(shí)時(shí)生成。
-
利用maskView實(shí)現(xiàn)圖片漸變切換動(dòng)畫
如圖1.2 的圖片切換效果,其實(shí)是使用了的alpha通道變化的maskView完成圖片的切換。

// 在底層的 圖片 background(最后要顯示出來(lái))
UIImageView *background = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
background.image = [UIImage imageNamed:@"base"];
background.center = self.view.center;
[self.view addSubview:background];
// 在上層的 圖片 upGround
UIImageView *upGround = [[UIImageView alloc] initWithFrame:background.frame];
upGround.image = [UIImage imageNamed:@"background"];
[self.view addSubview:upGround];
// maskView 由兩個(gè)分別加載 “mask1” “mask” 的imageView拼接而成。加在 上層圖片上 , 注意 兩張透明度漸變的圖片是重點(diǎn)。是它們使 上層圖片upGround 顯示 或者隱藏
UIView *mask = [[UIView alloc] initWithFrame:upGround.bounds];
upGround.maskView = mask;
UIImageView *picOne = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 400)];
picOne.image = [UIImage imageNamed:@"mask1"];
[mask addSubview:picOne];
UIImageView *picTwo = [[UIImageView alloc] initWithFrame:CGRectMake(100, -200, 100, 400)];
picTwo.image = [UIImage imageNamed:@"mask"];
[mask addSubview:picTwo];
// 兩個(gè)imageView的動(dòng)畫 使maskView的alpha通道由 1 變成 0 ,導(dǎo)致 上層圖片消失, 達(dá)到切換的效果
[UIView animateWithDuration:2.f delay:2.f options:0 animations:^{
picOne.y -= 400;
picTwo.y += 400;
} completion:^(BOOL finished) {
}];
-
maskView配合CAGradientLayer使用
這個(gè)例子實(shí)現(xiàn)了 iPhone的滑動(dòng)解鎖效果
1.首先構(gòu)建一個(gè) 顏色漸變的layer,可以使用CAGradientLayer這個(gè)類,你也可以像上一個(gè)例子一樣使用圖片,看起來(lái)像圖1.3.1就行。
關(guān)于CAGradientLayer的屬性詳細(xì)解析可參考CAGradientLayer的一些屬性解析
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
[self.view.layer addSublayer:gradientLayer];
gradientLayer.frame = CGRectMake(0, 200, self.view.width, 64);
gradientLayer.colors = @[
(__bridge id)[UIColor blackColor].CGColor,
(__bridge id)[UIColor whiteColor].CGColor,
(__bridge id)[UIColor blackColor].CGColor,
];
gradientLayer.locations = @[@0.25,@0.5,@0.75];
gradientLayer.startPoint = CGPointMake(0, 0.5);
gradientLayer.endPoint = CGPointMake(1, 0.5);

2.讓這個(gè)圖層動(dòng)起來(lái),加個(gè)動(dòng)畫。
// CAGradientLayer可用來(lái)處理顏色漸變,它的漸變色也可以做隱式動(dòng)畫
CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"locations"];
basicAnimation.fromValue = @[@0, @0, @0.25];
basicAnimation.toValue = @[@0.75, @1, @1];
basicAnimation.duration = 2.5;
basicAnimation.repeatCount = HUGE;
[gradientLayer addAnimation:basicAnimation forKey:nil];

3.讓UILabel上的文字成為CAGradientLayer的遮罩,完成。
// 設(shè)置 gradientLayer 的 mask 為 unLock 有透明度的地方 就露出來(lái)了
UILabel *unlock = [[UILabel alloc] initWithFrame:gradientLayer.bounds];
self.unlock = unlock;
unlock.alpha = 0.5;
unlock.text = @"滑動(dòng)來(lái)解鎖 >>";
unlock.textAlignment = NSTextAlignmentCenter;
unlock.font = [UIFont boldSystemFontOfSize:30];
gradientLayer.mask = unlock.layer;

-
maskView配合CAShapeLayer使用
直接上代碼,在圖片層上 加一層毛玻璃層,在毛玻璃層上加一層圓形的mask。

// 最底層的view 顯示圖片
UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
imageView.image = [UIImage imageNamed:@"Slice"];
[self.view addSubview:imageView];
// 創(chuàng)建mask
// 貝塞爾曲線(創(chuàng)建一個(gè)圓)
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(0, 0)
radius:100
startAngle:DEGREES(0)
endAngle:DEGREES(360)
clockwise:YES];
_maskLayer = [CAShapeLayer layer];
_maskLayer.path = path.CGPath;
_maskLayer.position = CGPointMake(_showView.bounds.size.width/2.f,
_showView.bounds.size.height/2.f);
_maskLayer.fillColor = [UIColor whiteColor].CGColor;
_maskLayer.position = self.view.center;
// 創(chuàng)建覆蓋在最底層imageView上的模糊圖片, 添加mask 注意mask為一個(gè)圓形(模糊圖片只會(huì)顯示一個(gè)圓,其他地方會(huì)變成透明)
UIView *blurView = [[UIView alloc] initWithFrame:self.view.bounds];
blurView.backgroundColor = [UIColor blackColor];
[self.view addSubview:blurView];
blurView.layer.mask = _maskLayer;
blurView.layer.contents = (__bridge id)([[UIImage imageNamed:@"Slice"] imgWithBlur].CGImage);
/*
透明的View,用于maskView中的ShapeLayer的參考View(用于拖拽)
*/
_showView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
_showView.backgroundColor = [UIColor clearColor];
_showView.center = self.view.center;
[self.view addSubview:_showView];
UIPanGestureRecognizer *recognizer =
[[UIPanGestureRecognizer alloc] initWithTarget:self
action:@selector(handlePan:)];
[_showView addGestureRecognizer:recognizer];
}
- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
// 拖拽
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
// 關(guān)閉CoreAnimation實(shí)時(shí)動(dòng)畫繪制(核心)
[CATransaction setDisableActions:YES];
_maskLayer.position = recognizer.view.center;
}
-
毛玻璃漸變效果
如圖1.5.1 效果 ,如果你理解了mask的原理,這個(gè)和上一個(gè)類似,
在圖片層上 加一層毛玻璃層,在毛玻璃層上加一層透明度漸變的mask,OK。

UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
imageView.image = [UIImage imageNamed:@"Slice"];
[self.view addSubview:imageView];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
[self.view.layer addSublayer:gradientLayer];
gradientLayer.frame = self.view.bounds;
// 顏色的透明度 alpha 0.0 全透過(guò) 1.0 不透明
gradientLayer.colors = @[
(__bridge id)[UIColor colorWithWhite:1 alpha:0.0].CGColor,
(__bridge id)[UIColor colorWithWhite:1 alpha:1.0].CGColor,
];
gradientLayer.locations = @[@0.35,@0.55];
_gradientLayer = gradientLayer;
UIView *blurView = [[UIView alloc] initWithFrame:self.view.bounds];
blurView.backgroundColor = [UIColor blackColor];
[self.view addSubview:blurView];
blurView.layer.mask = gradientLayer;
blurView.layer.contents = (__bridge id)([[UIImage imageNamed:@"Slice"] imgWithBlur].CGImage);
以上例子的代碼可以在這下載
另外推薦一個(gè)mask實(shí)現(xiàn)的動(dòng)畫效果,mask的實(shí)現(xiàn)方式非常巧妙。
https://github.com/andreamazz/BubbleTransition