Core Animation:CAKeyframeAnimation && mask

項目效果
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》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末着帽,一起剝皮案震驚了整個濱河市罩阵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌启摄,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件幽钢,死亡現(xiàn)場離奇詭異歉备,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)匪燕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進(jìn)店門蕾羊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人帽驯,你說我怎么就攤上這事龟再。” “怎么了尼变?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵利凑,是天一觀的道長。 經(jīng)常有香客問我嫌术,道長哀澈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任度气,我火速辦了婚禮割按,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘磷籍。我一直安慰自己适荣,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布院领。 她就那樣靜靜地躺著弛矛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪比然。 梳的紋絲不亂的頭發(fā)上汪诉,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼扒寄。 笑死鱼鼓,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的该编。 我是一名探鬼主播迄本,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼课竣!你這毒婦竟也來了嘉赎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤于樟,失蹤者是張志新(化名)和其女友劉穎公条,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迂曲,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡靶橱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了路捧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片关霸。...
    茶點故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖杰扫,靈堂內(nèi)的尸體忽然破棺而出队寇,到底是詐尸還是另有隱情,我是刑警寧澤章姓,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布佳遣,位于F島的核電站,受9級特大地震影響凡伊,放射性物質(zhì)發(fā)生泄漏苍日。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一窗声、第九天 我趴在偏房一處隱蔽的房頂上張望相恃。 院中可真熱鬧,春花似錦笨觅、人聲如沸拦耐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽杀糯。三九已至,卻和暖如春苍苞,著一層夾襖步出監(jiān)牢的瞬間固翰,已是汗流浹背狼纬。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留骂际,地道東北人疗琉。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像歉铝,于是被迫代替她去往敵國和親盈简。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,666評論 2 350

推薦閱讀更多精彩內(nèi)容