CoreAnimation詳解(一)有關Layer的動畫,coreanimationlayer

來源:互聯網
上載者:User

CoreAnimation詳解(一)有關Layer的動畫,coreanimationlayer

原創Blog,轉載請註明出處

我的IOS SDK詳解專欄,地址

http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html

本文主要從CoreAnimation的Layer角度來講解動畫,我想從CALayer的角度更好理解,後續還會有第二篇從UIKIt的UIView角度來講解動畫,第三篇講解UIDynamicAnimation,第三篇我會講到UIViewController切換時候的動畫。

本文主要涵蓋四個部分

1.基礎動畫-會講到時間函數和一些關鍵的屬性

2.基於主要畫面格的動畫-講到沿著指定路徑啟動並執行動畫

3.動畫組-多個動畫組合到一起形成複雜的動畫

4.簡單講一下講一下有關動畫的代理

(一)為什麼要設計動畫?

動畫提供了一個漸層的方式來表達變化,使用動畫可以避免各種介面突變,造成使用者困惑。

IOS中,使用CoreAnimation只要指定始末狀態或者主要畫面格的狀態,CoreAnimation會高效的為我們建立補間動畫。


(二)從CALayer的角度來看的三種動畫

首先不熟悉CALayer的同學看看前兩篇的CALayer的內容,這是CoreAnimation的基礎。這裡我重複的介紹兩種CALayer的Tree。

Presentation Tree-對應在動畫的過程中,CALayer的屬性

Model Tree-對應CALayer的實際屬性。

通過使用 -[CALayer presentationLayer] 和 -[CALayer modelLayer]可以訪問兩種Tree

動畫的過程實際上是修改Presentation Tree


2.1 基礎的動畫

第一個簡單的動畫,我希望imageview向右移動100的距離,移動方式easeInOut(加速開始,減速結束)。

效果

               

代碼如下,通常有兩種方式來影響動畫

<pre name="code" class="objc">    CABasicAnimation * animation = [CABasicAnimation animation];    animation.keyPath = @"position.x";//KVC的方式來訪問屬性    animation.fromValue = @(self.imageview.layer.position.x);//該屬性開始的值    animation.toValue = @(self.imageview.layer.position.x + 100);//結束的值    animation.duration = 1;//期間    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];//結束函數    [self.imageview.layer addAnimation:animation forKey:@"basic"];//添加動畫

通過fromValue和toValue是一種方式,當然也可以通過byValue的方式,byValue在初值上加上byValue的變化,通過以下代碼也可以實現上述動畫

 CABasicAnimation * animation = [CABasicAnimation animation];    animation.keyPath = @"position.x";    animation.byValue = @(100);    animation.duration = 1;    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];    [self.imageview.layer addAnimation:animation forKey:@"basic"];

但是,結束後會發現,imageview又恢複到原處。這是因為在動畫的過程中,我們修改的是Presentation Tree,並沒有實際修改CALayer的屬性。想要讓動畫停在結束的位置,通常有兩種方式,

(1)修改屬性

代碼如下

  CABasicAnimation * animation = [CABasicAnimation animation];    animation.keyPath = @"position.x";    animation.fromValue = @(self.imageview.layer.position.x);    animation.toValue = @(self.imageview.layer.position.x + 100);    animation.duration = 1;    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];    [self.imageview.layer addAnimation:animation forKey:@"basic"];    self.imageview.layer.position = CGPointMake(self.imageview.layer.position.x+100, self.imageview.layer.position.y);


(2)設定讓動畫停在結束的位置

<pre name="code" class="objc">  CABasicAnimation * animation = [CABasicAnimation animation];    animation.keyPath = @"position.x";    animation.fromValue = @(self.imageview.layer.position.x);    animation.toValue = @(self.imageview.layer.position.x + 100);    animation.duration = 1;    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];    animation.removedOnCompletion = NO;//動畫結束了禁止刪除    animation.fillMode = kCAFillModeForwards;//停在動畫結束處    [self.imageview.layer addAnimation:animation forKey:@"basic"];


一般採用前者,因為動畫往往的結束是實際的屬性的改變。

這裡再講解下時間函數

時間函數決定了動畫如何執行,時間函數決定了動畫的數學模型,比如速度速度最好不要有突變, 系統提供的時間函數有以下幾種

NSString *constkCAMediaTimingFunctionLinear;線性

NSString *constkCAMediaTimingFunctionEaseIn;加速進入

NSString *constkCAMediaTimingFunctionEaseOut;減速停止

NSString*constkCAMediaTimingFunctionEaseInEaseOut;加速進入減速停止,這個是常用的

NSString *constkCAMediaTimingFunctionDefault;預設

當然,時間函數支援自訂,用如下函數

functionWithControlPoints::::

這個函數的4個點決定了一個三維的貝茲路徑來決定時間函數。這裡不深入講解了。

最後,這一點尤為重要,就是在傳遞CAAnimation的對象或者子類給Layer的時候,傳遞的是copy

2.2 基於主要畫面格的動畫

以下是一個基於主要畫面格建立的抖動的動畫,採用在時間點對應的位置來建立動畫

  CAKeyframeAnimation * animation = [CAKeyframeAnimation animation];    animation.keyPath = @"position.x";    NSInteger initalPositionX = self.imageview.layer.position.x;    animation.values = @[@(initalPositionX),                         @(initalPositionX + 10),                         @(initalPositionX - 10),                         @(initalPositionX + 10),                         @(initalPositionX)];    animation.keyTimes = @[                           @(0),                           @(1/6.0),                           @(3/6.0),                           @(5/6.0),                           @(1)];    [self.imageview.layer addAnimation:animation forKey:@"keyFrame"];

當然,基於主要畫面格的動畫支援沿著路徑運動,可以設定時間函數來決定運動的方式

例如以下建立一個比較複雜的運動,首先移動到(200,200),然後沿著以該點為圓心,逆時針旋轉半圈,最後停在結束的位置。

動畫的過程中,imageview沿著路徑轉動

    CAKeyframeAnimation * animation = [CAKeyframeAnimation animation];    animation.keyPath = @"position";    //Create Path    CGMutablePathRef mutablepath = CGPathCreateMutable();    CGPathMoveToPoint(mutablepath, nil,self.imageview.layer.position.x, self.imageview.layer.position.y);    CGPathAddLineToPoint(mutablepath,nil,200,200);    CGPathAddArc(mutablepath, nil,200,200,100,0,M_PI,YES);    //set path    animation.path = mutablepath;    animation.duration = 4.0;    animation.rotationMode = kCAAnimationRotateAuto;    animation.removedOnCompletion = NO;//動畫結束了禁止刪除    animation.fillMode = kCAFillModeForwards;//停在動畫結束處    [self.imageview.layer addAnimation:animation forKey:@"PathAnimation"];
這個動畫的幾幅關鍵


                  


2.3 動畫組

所謂,動畫組就是把幾個動畫組合到一起,然後一起執行,通常複雜的動畫都是由動畫組來實現的。

舉個例子:沿著上個例子的路徑運動,運動的同時透明度漸層。

  CAKeyframeAnimation * pathAnimation = [CAKeyframeAnimation animation];    pathAnimation.keyPath = @"position";    //Create Path    CGMutablePathRef mutablepath = CGPathCreateMutable();    CGPathMoveToPoint(mutablepath, nil,self.imageview.layer.position.x, self.imageview.layer.position.y);    CGPathAddLineToPoint(mutablepath,nil,200,200);    CGPathAddArc(mutablepath, nil,200,200,100,0,M_PI,YES);    //set path    pathAnimation.path = mutablepath;    pathAnimation.rotationMode = kCAAnimationRotateAuto;    [self.imageview.layer addAnimation:pathAnimation forKey:@"PathAnimation"];        //透明度變化    CAKeyframeAnimation * opacityAnimation = [CAKeyframeAnimation animation];    opacityAnimation.keyPath = @"opacity";    opacityAnimation.values = @[@(1.0),                         @(0.5),                         @(0.0),                         @(0.5),                         @(1.0)];    opacityAnimation.calculationMode = kCAAnimationPaced;    [self.imageview.layer addAnimation:opacityAnimation forKey:@"OpacityAnination"];    //配置動畫組    CAAnimationGroup * animationGroup = [[CAAnimationGroup alloc] init];    animationGroup.animations = @[pathAnimation,opacityAnimation];    animationGroup.duration = 4.0;    animationGroup.removedOnCompletion = NO;    animationGroup.fillMode = kCAFillModeBackwards;    [self.imageview.layer addAnimation:animationGroup forKey:@"GroupAnimation"];
效果的幾幅

            

(三)動畫的代理

通過設定代理可以監聽動畫開始和結束的事件

通過設定delegate,來監聽兩個函數

animationDidStart:(CAAnimation *)anim

animationDidStop:(CAAnimation *)anim finished:(BOOL)flag

這裡的flag判斷動畫是否執行完畢


最後,附上wiki上設計動畫的12個基本原則

https://en.wikipedia.org/wiki/12_basic_principles_of_animation

BTY:有沒有同學知道CSDN怎麼插入gif圖片?

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.