項目效果
CALay屬性mask
我們可以比較簡單地通過masksToBounds屬性沿邊界裁剪圖形,通過cornerRadius屬性設(shè)定一個圓角,但當(dāng)遇到展現(xiàn)的內(nèi)容不是一個規(guī)則的圓或者矩形的時候,例如,一個有星形的圖片。此時,我們便可以使用CALayer的mask屬性去實現(xiàn)圖層遮罩兰绣。
@property(nullable, strong) CALayer *mask;
可以看到mask屬性本身就是一個CALayer類型,除此之外,mask屬性定義了父圖層的部分可見區(qū)域。當(dāng)mask圖層比父圖層小的時候,此時便會只展現(xiàn)mask圖層里面的內(nèi)容,mask圖層以外的圖層的內(nèi)容會被隱藏(不顯示)叫挟。
- 簡單展示mask屬性的簡單使用
創(chuàng)建項目,在storyBoard中添加一個UIImageView,添加相應(yīng)約束(水平方向、垂直方向居中顯示删铃、固定寬高為60),拖入相關(guān)資源圖片缀蹄。
1.創(chuàng)建CALayer實例maskLayer
CALayer *maskLayer = [CALayer layer];
2.設(shè)置maskLayer的contents屬性(需要CGImageRef類型)
maskLayer.contents = (__bridge id) [UIImage imageNamed:@"logo"].CGImage;
3.設(shè)置maskLayer屬性的frame
maskLayer.frame = self.imageView.bounds;
4.設(shè)置mask遮罩
self.imageView.layer.mask = maskLayer;
最后comm + R,你會看到星形的圖片已經(jīng)很順利的生成了。
5.星形效果
那要完成前文的效果還需要其他什么動畫知識呢猜惋?CAKeyframeAnimation(關(guān)鍵幀動畫)你值得擁有。
CAKeyframeAnimation
CAKeyframeAnimation為圖層對象提供了關(guān)鍵幀動畫的能理,其可以指定keyframe的值去控制動畫的時間和動畫的行為培愁。
- 常用屬性介紹
1.創(chuàng)建CAKeyframeAnimation對象
+ (instancetype)animationWithKeyPath:(nullable NSString *)path;
通過設(shè)置方法的參數(shù)path去設(shè)置動畫的keyPath屬性
2.設(shè)置動畫的時間
@property CFTimeInterval duration;
3.設(shè)置動畫開始的時間
@property CFTimeInterval beginTime;
4.設(shè)置每一關(guān)鍵幀的值
@property(nullable, copy) NSArray *values;
5.設(shè)置一個關(guān)鍵幀到另一個關(guān)鍵幀的時間(值為0-1)
@property(nullable, copy) NSArray<CAMediaTimingFunction *> *timingFunctions;
介紹完常用屬性,那么就開始我們的項目吧著摔。
項目效果的實現(xiàn)
該項目是一個較為簡單的啟動動畫效果。前面我們已經(jīng)較為順利地使用mask屬性去得到了星形的圖片,那么我在此基礎(chǔ)上修改我們的代碼,實現(xiàn)效果定续。準(zhǔn)備工作
1.新建工程,拖入相關(guān)的資源圖片谍咆。在storyboard界面,給控制器Embed In一個Navigation Controller。并在ViewController中拖入一個UIImageView控件并設(shè)置約束(top私股、left摹察、bottom、right與父視圖重合),設(shè)置image屬性倡鲸。
2.在LaunchScreen.storyboard中拖入UIIimageView并設(shè)置約束(水平供嚎、垂直方向均保持居中,固定寬高為60),設(shè)置背景顏色為橘黃色,并設(shè)置圖片的image為星形圖片
3.在application: didFinishLaunchingWithOptions:方法中進(jìn)行相關(guān)動畫(實際開發(fā)中可將動畫代碼寫在自定義類中方便管理)實現(xiàn)思路
我們已經(jīng)在LaunchScreen.storyboard設(shè)置好了啟動時的星形圖片,而在項目效果圖中,我們可以看到啟動圖片消失后,星形圖片依然存在。因此我們可以在ViewController的view中添加一個星形的mask遮罩,并將其位置設(shè)置為與啟動圖中的星形圖片的位置相同。然后再對控制器的view的mask進(jìn)行動畫操作克滴。代碼分解
使用UIStoryboard的相關(guān)方法獲取UINavigationController
UINavigationController *naVC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateInitialViewController];
self.window.rootViewController = naVC;
- 實現(xiàn)星形遮罩
CALayer *maskLayer = [CALayer layer];
maskLayer.contents = (__bridge id)[UIImage imageNamed:@"logo"].CGImage;
maskLayer.position = naVC.view.center;
maskLayer.bounds = CGRectMake(0, 0, 60, 60);
naVC.view.layer.mask = maskLayer;
此時啟動應(yīng)用,我們會發(fā)現(xiàn)啟動圖片消失后,除了星形圖片以外,其他的界面并不是我們效果中的橘黃色而是黑色,產(chǎn)生這個問題的原因是window的背景顏色為黑色,那么我們就簡單粗暴地去解決這個問題,直接設(shè)置window的背景顏色和啟動界面的背景顏色相同逼争。
self.window.backgroundColor = [UIColor orangeColor];
從效果圖中可以看到控制器中星形的內(nèi)容是逐漸可見的,而到上一步我們的效果是啟動界面結(jié)束后,就直接看到了星形的內(nèi)容。因此我們做進(jìn)一步處理劝赔。
創(chuàng)建一個白色的view對控制器的內(nèi)容進(jìn)行遮罩,并緩慢消失最后移除誓焦。
UIView *whiteView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
whiteView.backgroundColor = [UIColor whiteColor];
[naVC.view addSubview:whiteView];
[naVC.view bringSubviewToFront:whiteView];
[UIView animateWithDuration:0.1 delay:1 options:UIViewAnimationOptionCurveEaseIn animations:^{
whiteView.alpha = 0;
} completion:^(BOOL finished) {
[whiteView removeFromSuperview];
}];
- 為mask圖層添加關(guān)鍵幀動畫
CAKeyframeAnimation *maskLayerAnimation = [CAKeyframeAnimation animationWithKeyPath:@"bounds"];
maskLayerAnimation.duration = 1;
maskLayerAnimation.beginTime = CACurrentMediaTime() + 1.0f;//延遲一秒
CGRect startRect = maskLayer.frame;
CGRect tempRect = CGRectMake(0, 0, 100, 100);
CGRect finalRect = CGRectMake(0, 0, 2000, 2000);
maskLayerAnimation.values = @[[NSValue valueWithCGRect:startRect], [NSValue valueWithCGRect:tempRect], [NSValue valueWithCGRect:finalRect]];maskLayerAnimation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
// 默認(rèn)情況下動畫結(jié)束后會回到初始狀態(tài),設(shè)置下面的兩個屬性可使動畫結(jié)束后不回到初始位置并保持最后的狀態(tài)
maskLayerAnimation.removedOnCompletion = NO;
maskLayerAnimation.fillMode = kCAFillModeForwards;
// 為圖層添加動畫效果
[naVC.view.layer.mask addAnimation:maskLayerAnimation forKey:@"logoMaskAnimaiton"];
- 對控制器的內(nèi)容進(jìn)行簡單的縮放
[UIView animateWithDuration:0.25 delay:1.3 options:UIViewAnimationOptionTransitionNone animations:^{
naVC.view.transform = CGAffineTransformMakeScale(1.05, 1.05);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
naVC.view.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
naVC.view.layer.mask = nil;
}];
}];
最后,command + R看看效果吧。
tips:為了使動畫銜接完整,多調(diào)試各個動畫的動畫時間
向KITTEN
本文GitHub地址:
https://github.com/RookieAngry/Demo_CAKeyframeAnimation.git
項目來源于KITTEN大神的《A GUIDE TO IOS ANIMATION》