iOS動畫系列之七:實現相似Twitter的啓動動畫

來來來,今天我們經過實現一個相似Twitter的啓動動畫來看看CAKeyFrame Animation和CAAnimation Group怎麼玩。git

因此今天我們的重點到了第七章,CAKeyFrame Animation和CAAnimation Group。最後的那個啓動動畫徹底是爲了實踐一下看看CAKeyFrame Animation和CAAnimation Group怎麼使用。swift

有讀者私下說更新速度太慢了。在碼雲上看了一下下載的統計,發現其實下載的童鞋並非特別多。若是隻是看看思路,或者複習一下這些基礎知識,確實是很快。可是若是對於這些內容不是特別熟悉,建議仍是敲一邊代碼,看看本身能碰到什麼坑。bash

俺寫一篇分享文章大約要4~6個小時,大致是三部分:想到合適的例子,敲代碼寫註釋,寫文章。一般都會看本身當前的狀況,決定是先寫swift版仍是OC版,而後不動腦子的翻譯成另一版調整一下BUG。這樣也是爲了訓練本身,前段時間發現本身有時候會不自覺的把兩種語言混在一塊兒,這個習慣特別很差,因此想用這種方式本身糾正一下。到最後更新寫文章的時候反而更輕鬆了,由於不用動腦。哈哈~併發

Come on~下面這張圖純粹是爲了簡書看成封面使用的。也不知道爲何,之前簡書還能自動把GIF的第一楨看成封面,如今很差使了。app

CAKeyFrame Animation和CAAnimation Group.png
CAKeyFrame Animation和CAAnimation Group.png

下面展現一下寫完以後的成果:佈局

ani.gif
ani.gif

源代碼能夠在這裏下載,裏面有OC和Swift兩版。git.oschina.net/atypical/CA…學習

iOS動畫系列之CAKeyFrame Animation和CAAnimation Group(OC和Swift兩版)動畫

1. CAKeyframeAnimation

CAKeyframeAnimation是CApropertyAnimation的子類,跟CABasicAnimation的區別是:CABasicAnimation只能從一個數值(fromValue)變到另外一個數值(toValue),而CAKeyframeAnimation會使用一個NSArray保存這些數值。ui

建立步驟:spa

  1. 建立關鍵幀動畫對象
  2. 設置屬性
  3. 添加到要做用的layer上
  • 若是使用rect橢圓的方式,動畫會不連貫,停頓一下。緣由是由於矩形的周長比橢圓的長,動畫路徑按照橢圓執行完以後,須要等待一下最大周長走完。
    這些都是由於計算模式致使的。

1.1 建立一個抖動的小方塊

咱們用一個簡單的demo來感覺一下CAKeyframeAnimation,來作一個會抖動的小方塊。

抖動的小方塊.gif
抖動的小方塊.gif

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
//設置一些列的關鍵幀動畫
    animation.values = @[@(-M_PI_4 / 5),@(M_PI_4 / 5),@(-M_PI_4 / 5)];
    animation.repeatCount = CGFLOAT_MAX;
    [self.view.layer addAnimation:animation forKey:@"rotation"];複製代碼

1.2 建立一個沿橢圓路徑運動的小飛機

咱們建立一個UIBezierPath,讓小飛機沿着這個路徑運動。

//建立動畫對象
    CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//設置屬性:建立beziper路徑,並把路徑做爲運動軌跡
    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 200, 500)];
    keyFrameAnimation.path = bezierPath.CGPath;
//設置動畫時間
    keyFrameAnimation.duration = 2;
//設置動畫循環播放的次數
    keyFrameAnimation.repeatCount = CGFLOAT_MAX;
//設置動畫的計算模式
    keyFrameAnimation.calculationMode = kCAAnimationPaced;

//將動畫添加到layer上
    [self.planeView.layer addAnimation:keyFrameAnimation forKey:nil];複製代碼

1.3 動畫疊加

剛纔添加了一個沿路徑運動的飛機,咱們同時還能夠給飛機再把抖動的那個動畫也添加上去。前幾篇提到後面那個forKey,可能還有童鞋不知道幹啥用。如今看到了木有?一個layer裏面好幾個動畫,如何找到對應的動畫吶?如今經過這個key就能找到了。

//        爲小飛機同時添加抖動的動畫和橢圓路徑旋轉的動畫
    [self.planeImageView.layer addAnimation:[self shakeAni] forKey:nil];
    [self.planeImageView.layer addAnimation:[self ovalAni] forKey:nil];複製代碼

2. CAAnimationGroup

單一的動畫在實際中每每是不能知足需求的,這時就須要用到動畫組。

  • 是CAAnimation的子類
  • 能夠保存一組動畫對象,將CAAnimationGroup對象加入圖層後,組中全部動畫對象能夠同時併發運行.

咱們試着作一個包行旋轉、縮放、按必定弧度路徑組合在一塊兒的動畫。效果以下:

arcAni.gif
arcAni.gif

- (CAAnimationGroup *)groupAni{
    //        實例化一個組動畫對象
        CAAnimationGroup *groupAni = [[CAAnimationGroup alloc] init];

    //        建立旋轉的動畫
        CABasicAnimation *basicRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    basicRotation.toValue = @(M_PI * 2);

    //        建立縮放的動畫
        CABasicAnimation *basicScale = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    basicScale.toValue = @(0.2);

    //        建立按照路徑移動的動畫
        CAKeyframeAnimation *keyFrameAni = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *arcPath = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:150 startAngle:0 endAngle:M_PI * 2 clockwise:YES];

    keyFrameAni.path = arcPath.CGPath;
    keyFrameAni.calculationMode = kCAAnimationPaced;
    keyFrameAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    //        將旋轉、縮放、移動的動畫添加到組動畫中
    groupAni.animations = @[basicRotation,basicScale,keyFrameAni];
    //        組動畫重複次數
        groupAni.repeatCount = CGFLOAT_MAX;
    //        組動畫時長
        groupAni.duration = 2;

    return groupAni;
}複製代碼

3. 實現相似Twitter的啓動動畫

3.1實現思路

1,在View上設置一個東西可以遮擋住背景圖;
2,把遮罩變成五角星;
3,讓遮罩慢慢變大,中間可見區域愈來愈大。

yes!思路就是這樣的。那怎麼遮住背景圖片呢?

3.2 CALayer的遮罩屬性

CALayer自己有一個屬性,叫mask。咱們來看一下官方解釋:

@property(nullable, strong) CALayer *mask;

When true an implicit mask matching the layer bounds is applied to
the layer (including the effects of the `cornerRadius' property). If both `mask' and `masksToBounds' are non-nil the two masks are multiplied to get the actual mask values. Defaults to NO. Animatable.複製代碼

它相似於一個子圖層,相對於父圖層(即擁有該屬性的圖層)佈局,可是它卻不是一個普通的子圖層。不一樣於其餘可以在父圖層中繪製出圖像的子圖層,mask圖層定義了父圖層的部分可見區域。

mask圖層的Color屬性是可有可無的,真正重要的是圖層的輪廓。也就是說mask圖層實心的部分會被保留下來,其餘的則會被拋棄。若是mask圖層比父圖層要小,只有在mask圖層裏面的內容纔是它關心的,除此之外的一切都會被隱藏起來。

Paste_Image.png
Paste_Image.png

3.3 實現相似Twitter的啓動動畫

好了準備工做都作完了,咱們就開始寫這個動畫了。這個動畫其實就是一個簡單的CAKeyframeAnimation。設置了三個關鍵幀動畫的大小,以及這三個關鍵幀的運動節奏。

而後,就好啦~而後,就好啦~而後,就好啦~而後,就好啦~

哪尼?!!!就這樣?!!對啊,就這樣。

- (CAKeyframeAnimation *)maskAni{
 //        放大縮小視圖,keypath使用bounds
 CAKeyframeAnimation *maskAni = [CAKeyframeAnimation animationWithKeyPath:@"bounds"];
 //        動畫時間
 maskAni.duration = 30.75;
 //        動畫延遲0.5秒播放
 maskAni.beginTime = CACurrentMediaTime() + 0.5;


 //        設置關鍵幀動畫的數值
 CGRect startRect = self.maskLayer.frame;

 CGRect tempRect = CGRectMake(0, 0, 100, 100);

 CGRect finalRect = CGRectMake(0, 0, 2000, 2000);
 maskAni.values = @[[NSValue valueWithCGRect:startRect],[NSValue valueWithCGRect:tempRect],[NSValue valueWithCGRect:finalRect]];


 //        設置關鍵幀動畫的運動節奏
 maskAni.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];


 //        動畫播放結束後是否移除動畫
 maskAni.removedOnCompletion = NO;

 //        動畫填充模式:kCAFillModeForwards:當動畫結束後,layer會一直保持着動畫最後的狀態
 maskAni.fillMode = kCAFillModeForwards;

 return maskAni;


 }複製代碼

留一個小問題

我在OC和Swift裏面對不一樣的View使用了mask。一個是給背景圖片的UIImageView設置了mask,另外一個是直接給Controller的View設置了mask。設置這兩個有神馬區別咩?


好,下篇其實有一個重頭,就是CAShapeLayer。由於在工做中碰到的大部分動畫都是經過UIView的動畫block實現,其餘都基本上都是須要用到CAShapeLayer。咱們下次玩點好玩的吧~
若是還有興趣,能夠看看本系列的其餘文章哈。

-----------------------華麗分割線,iOS動畫系列全集連接-------------------------------------------------
第一篇:iOS動畫系列之一:經過實戰學習CALayer和透視的原理。作一個帶時分秒指針的時鐘動畫(上)
第二篇:iOS動畫系列之二:經過實戰學習CALayer和透視的原理。作一個帶時分秒指針的時鐘動畫。包含了OC和Swift兩種源代碼(下)
第三篇:iOS動畫系列之三:Core Animation。介紹了Core Animation的經常使用屬性和方法。
第四篇:CABasic Animation。iOS動畫系列之四:基礎動畫之平移篇
第五篇:CABasic Animation。iOS動畫系列之五:基礎動畫之縮放篇&旋轉篇
第六篇:iOS動畫系列之六:利用CABasic Animation完成帶動畫特效的登陸界面
第七篇:iOS動畫系列之七:實現相似Twitter的啓動動畫
第八篇:iOS動畫系列之八:使用CAShapeLayer繪畫動態流量圖
第九篇:iOS動畫系列之九:實現點讚的動畫及播放起伏指示器
第十篇:實戰系列:繪製過山車場景

相關文章
相關標籤/搜索