iOS開發(fā)經(jīng)驗(9)-動畫

目錄:
  1. UIView動畫
  2. Core Animation
  3. 自定義轉(zhuǎn)場動畫
  4. UIDynamicAnimator彈簧動畫

關(guān)于繪圖和動畫有兩種處理的方式:CPU(中央處理器)和GPU(圖形處理器)润梯。在現(xiàn)代iOS設(shè)備中陋葡,都有可以運行不同軟件的可編程芯片,但是由于歷史原因,我們可以說CPU所做的工作都在軟件層面撵溃,而GPU在硬件層面形病。

總的來說粘驰,我們可以用軟件(使用CPU)做任何事情椿胯,但是對于圖像處理,通常用硬件會更快魂爪,因為GPU使用圖像對高度并行浮點運算做了優(yōu)化先舷。由于某些原因,我們想盡可能把屏幕渲染的工作交給硬件去處理滓侍。問題在于GPU并沒有無限制處理性能蒋川,而且一旦資源用完的話,性能就會開始下降了(即使CPU并沒有完全占用)粗井。

1. UIView動畫

在UIView類中共有三個類目(Category)用于實現(xiàn)動畫功能,分為UIViewAnimation尔破、UIViewAnimationWithBlocks以及UIViewKeyframeAnimations,他們是對核心動畫(Core Animation)的封裝,可以讓我們不進行任何繪畫等復(fù)雜操作的前提下實現(xiàn)大部分動畫需求
UIView動畫就是利用UIView的API來實現(xiàn)動畫效果。而利用UIView API也可以分為兩種浇衬,一種block形式懒构,一種多API組合。
一耘擂、一般形式的UIView動畫

#pragma mark - 一般形式的UIView動畫

- (void)baseViewAnimation
{
    [UIView beginAnimations:@"centerAnimation" context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];
    [UIView setAnimationDuration:2.0];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationWillStartSelector:@selector(animationWillStart)];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop)];

    self.testView.center = CGPointMake(K_width/2, 64);
    [UIView commitAnimations];
}

- (void)animationWillStart
{
    self.testView.transform = CGAffineTransformMakeScale(0.2, 0.2);
}
- (void)animationDidStop
{
    self.testView.transform = CGAffineTransformIdentity;;
}

二胆剧、block形式的UIView動畫
在animations block中只能修改UIView的部分屬性,產(chǎn)生動畫效果醉冤。而可以產(chǎn)生動畫效果的屬性秩霍,蘋果在其注釋中都有標記 animatable。
1. 最簡單的UIView動畫API
第一個參數(shù)是動畫執(zhí)行時長(單位:秒)蚁阳;第二個參數(shù)就是動畫的block铃绒,屬性變化信息的最終值。

[UIView animateWithDuration:3.0 animations:^{
        self.testView.frame = CGRectMake(50, 50, 100, 100);
}];

2. 比方法1多了一個延遲時間(單位:秒)和動畫類型
延遲時間是表示多久之后執(zhí)行該動畫螺捐,動畫執(zhí)行類型有樣式颠悬,比如速度先快后慢矮燎,開始快中間慢結(jié)束時再快,勻速等等赔癌〉猓可以移除設(shè)置不同的枚舉值來比較。

#pragma mark - block形式的UIView動畫
- (void)blockAnimation_1
{
    [UIView animateWithDuration:3.0 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        self.testView.center = CGPointMake(K_width/2, K_height-self.testView.bounds.size.height/2);
    } completion:^(BOOL finished) {
        [self.testView removeFromSuperview];
    }];
}

3. 彈性動畫
像橡皮筋一樣灾票,將試圖改變至屬性所設(shè)置的值后峡谊,會有一個回彈效果。根據(jù)設(shè)置的初速度和阻尼系數(shù)慢慢停止刊苍,最終停留在屬性所設(shè)置的值的狀態(tài)既们。
相比于方法2,多了一個damping阻尼系數(shù)和初速度

- (void)blockAnimation_2 // 彈性動畫
{
    
    /*
     usingSpringWithDamping: 震動效果班缰,取值范圍在0.0~1.0贤壁, 取值越小,震蕩幅度越大
     initialSpringVelocity:初始速度埠忘,數(shù)值越大初始速度越快。確定了在動畫結(jié)束之前運動的速度馒索。一般情況下都是設(shè)置為0莹妒。設(shè)值舉個例子來說,如果想要移動的距離為200pt绰上,移動速度為100pt/s旨怠,就需要設(shè)置為0.5。
  options:動畫的過渡效果
     */
    [UIView animateWithDuration:2 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        self.testView.center = CGPointMake(K_width/2, K_height-self.testView.bounds.size.height/2-10);
    } completion:^(BOOL finished) {
    }];
}

4. 關(guān)鍵幀動畫
UIView動畫現(xiàn)在只支持屬性關(guān)鍵幀動畫蜈块,不支持路徑關(guān)鍵幀動畫

[UIView animateKeyframesWithDuration:(NSTimeInterval)//動畫持續(xù)時間
                                delay:(NSTimeInterval)//動畫延遲執(zhí)行的時間
                              options:(UIViewKeyframeAnimationOptions)//動畫的過渡效果
                           animations:^{
                         //執(zhí)行的關(guān)鍵幀動畫
 }
                           completion:^(BOOL finished) {
                         //動畫執(zhí)行完畢后的操作
 }];

增加關(guān)鍵幀的方法:

 [UIView addKeyframeWithRelativeStartTime:(double)//動畫開始的時間(占總時間的比例)
                         relativeDuration:(double) //動畫持續(xù)時間(占總時間的比例)
                               animations:^{
                             //執(zhí)行的動畫
 }];

具體實現(xiàn)方法

- (void)blockAnimation_3 // 關(guān)鍵幀動畫
{
    
    [UIView animateKeyframesWithDuration:5 delay:0 options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionCurveLinear animations:^{
        //第一個關(guān)鍵幀:從0秒開始持續(xù)50%的時間鉴腻,也就是5.0*0.5=2.5秒
        [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{
            self.testView.center = CGPointMake(K_width/2, K_height-self.testView.bounds.size.height/2-10);
        }];
        
        //第二個關(guān)鍵幀:從50%時間開始持續(xù)25%的時間,也就是5.0*0.25=1.25秒
        [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.25 animations:^{
            self.testView.center = CGPointMake(0, 0);
        }];
        //第三個關(guān)鍵幀:從75%時間開始持續(xù)25%的時間百揭,也就是5.0*0.25=1.25秒
        [UIView addKeyframeWithRelativeStartTime:0.75 relativeDuration:0.25 animations:^{
            self.testView.center = CGPointMake(K_width/2, K_height/2);
        }];
    } completion:^(BOOL finished) {
        
    }];
}

關(guān)鍵幀動畫的options多了一些選擇

/* 動畫模式選擇爽哎,選擇一個 */
UIViewKeyframeAnimationOptionCalculationModeLinear/*< 連續(xù)運算模式 */
UIViewKeyframeAnimationOptionCalculationModeDiscreter/*< 離散運算模式 */
UIViewKeyframeAnimationOptionCalculationModePacedr/*< 均勻執(zhí)行運算模式 */
UIViewKeyframeAnimationOptionCalculationModeCubicr/*< 平滑運算模式 */
UIViewKeyframeAnimationOptionCalculationModeCubicPacedr/*< 平滑均勻運算模式 */

5. 轉(zhuǎn)場動畫
第一種:單個視圖的過渡效果

- (void)transitionWithView_4 // 轉(zhuǎn)場動畫
{
    /*
     以上方式可以在改變視圖的屬性時產(chǎn)生動畫,如果視圖添加或者移除的時候想要添加動畫器一,就要用到下面的方式了
     */

    UIViewAnimationOptions option = UIViewAnimationOptionCurveLinear | UIViewAnimationOptionTransitionFlipFromLeft;
    
    [UIView transitionWithView:self.imageview duration:10.0 options:option animations:^{
        UIImage *image = [UIImage imageNamed:@"maskImage"];
        self.imageview.image = image;
    } completion:^(BOOL finished) {
        
    }];
}

轉(zhuǎn)場動畫options多了一些選擇:

/* 轉(zhuǎn)場類型 */
UIViewAnimationOptionTransitionNone/*< 沒有轉(zhuǎn)場動畫效果 */
UIViewAnimationOptionTransitionFlipFromLeft/*< 從左側(cè)翻轉(zhuǎn)效果 */
UIViewAnimationOptionTransitionFlipFromRight/*< 從右側(cè)翻轉(zhuǎn)效果 */
UIViewAnimationOptionTransitionCurlUp/*< 向后翻頁的動畫過渡效果 */  
UIViewAnimationOptionTransitionCurlDown/*< 向前翻頁的動畫過渡效果 */   
UIViewAnimationOptionTransitionCrossDissolve/*< 溶解消失效果 */ 
UIViewAnimationOptionTransitionFlipFromTop/*< 從上方翻轉(zhuǎn)效果 */
UIViewAnimationOptionTransitionFlipFromBottom/*< 從底部翻轉(zhuǎn)效果 */

第二種:兩個視圖之間轉(zhuǎn)場可以使用,從舊視圖轉(zhuǎn)到新視圖的動畫效果
默認情況课锌,轉(zhuǎn)出的視圖會從父視圖移除,轉(zhuǎn)入后重新添加在該動畫過程中祈秕,fromView 會從父視圖中移除渺贤,并講 toView 添加到父視圖中,注意轉(zhuǎn)場動畫的作用對象是父視圖(過渡效果體現(xiàn)在父視圖上)请毛。

- (void)transitionWithView_5 // 轉(zhuǎn)場動畫
{
    /*
     這是一個便捷的視圖過渡 API志鞍,在動畫過程中,首先將 fromView 從父視圖中刪除方仿,然后將 toView 添加固棚,就是做了一個替換操作统翩。
     
     在需要視圖更改時,這個將變得特別有用玻孟。
     */
    UIViewAnimationOptions option = UIViewAnimationOptionCurveLinear | UIViewAnimationOptionTransitionFlipFromLeft;

    [UIView transitionFromView:self.testView toView:self.imageview duration:5 options:option completion:^(BOOL finished) {
        
    }];
}

調(diào)用該方法相當(dāng)于執(zhí)行下面兩句代碼:

[fromView.superview addSubview:toView];
[fromView removeFromSuperview];
2. Core Animation

定義:

Core Animation唆缴,中文翻譯為核心動畫,它是一組非常強大的動畫處理API黍翎,使用它能做出非常炫麗的動畫效果面徽,而且往往是事半功倍。也就是說匣掸,使用少量的代碼就可以實現(xiàn)非常強大的功能趟紊。
Core Animation 是跨平臺的,可以用在Mac OS X 和iOS 平臺碰酝。
Core Animation 的動畫執(zhí)行過程都是在后臺操作的霎匈,不會阻塞主線程。不阻塞主線程送爸,可以理解為在執(zhí)行動畫的時候還能點擊(按鈕)铛嘱。
要注意的是,Core Animation 是直接作用在 CALayer 上的袭厂,并非UIView墨吓,iOS 的 UIView 背后都有一個對應(yīng)的 CALayer。對 UIView 的修改實際上都是對背后 CALayer 的修改纹磺。
當(dāng) CALayer 在背后支持一個 UIView 的時候帖烘,UIView 就是它的 delegate。即橄杨,UIView 是 CALayer 的CALayerDelegate秘症。
即 Core Animation 不改變 UIView 的 Frame 屬性,也就是說并不改變 UIView 的實際位置式矫。

圖層樹和模型樹
CALayer 的同一個屬性值乡摹,會分別保存在模型層 modelLayer ,和展現(xiàn)層 presentationLayer 中衷佃。當(dāng)我們修改屬性值時趟卸,是修改的模型層的數(shù)值,動畫時系統(tǒng)根據(jù)模型層的變化氏义,生成的過渡值锄列,是保存在展現(xiàn)層中的。
在CALayer 的對象里能直接訪問到這兩層的信息惯悠。而CALayer 的底層實現(xiàn)實際不止這兩層邻邮,但我們現(xiàn)在討論動畫的時候,可以只關(guān)心這兩層克婶。

在整個動畫過程中筒严,呈現(xiàn)出來的過程是這樣的:
動畫前丹泉,顯示模型層的當(dāng)前值;
動畫開始鸭蛙,切換顯示展現(xiàn)層的值摹恨;
動畫過程中,展現(xiàn)層的值根據(jù)時間變化娶视,我們看到的實際是展現(xiàn)層的值在變化晒哄;
動畫結(jié)束,切換回顯示模型層的值肪获,此時模型層的值應(yīng)被修改為動畫結(jié)束時的值寝凌。
由于在動畫過程中,修改的只是展現(xiàn)層的值孝赫,模型層的值并沒有改變较木,所以Core Animation 并不修改 UIView 的實際位置。(如果要修改UIView 的實際位置青柄,則要手動修改 UIView 的 Frame)

UIKit動畫和Core Animation
UIKit實現(xiàn)的動畫效果往往都可以滿足你對動畫的需求伐债,而且實現(xiàn)代碼非常簡單,就像Core Animation的隱式動畫一樣致开,只需要在UIKit事務(wù)中修改相應(yīng)可動畫屬性即可泳赋,所以,一般情況下UIKit動畫是你優(yōu)先選擇的方式喇喉,但這里有一個誤區(qū),有很多人在講述iOS動畫的時候校坑,會把UIKit動畫和Core Animation動畫定義成兩種完全不同的處理方式拣技,并且認為Core Animation動畫的性能會更優(yōu)一些,但事實并非如此耍目,UIKit動畫和Core Animation動畫是相關(guān)連的膏斤。
UIKit雖然提供了非常簡便的API來實現(xiàn)動畫,但UIKit動畫畢竟是Core Animation動畫的一個抽象物邪驮,能提供的效果還是很有限的莫辨。
UIKit動畫其內(nèi)部實現(xiàn)是Core Animation動畫。UIView對象的rootlayer的隱式動畫是默認關(guān)閉的毅访。

顯式動畫和隱式動畫
Core Animation動畫有兩種形式沮榜,分別是顯式動畫和隱式動畫,但不管以哪種形式實現(xiàn)動畫喻粹,都是基于CAAnimation來實現(xiàn)的蟆融,所以這兩種動畫形式的主要差異在于,是否顯式創(chuàng)建CAAnimation對象來實現(xiàn)動畫守呜,當(dāng)然它們還存在其它的差異型酥,例如山憨,隱式動畫是基于CABasicAnimation對來實現(xiàn)的,而顯式動畫可以有更多的選擇弥喉,可以是CABasicAnimation郁竟,CAKeyframeAnimation,CATransition等由境。
對于獨立CALayer而言棚亩,隱式動畫是默認開啟的,只需要更改可動畫屬性就會觸發(fā)隱式動畫藻肄,但對于UIView的rootlayer而言蔑舞,隱式動畫是默認關(guān)閉的。
雖然隱式動畫的大部份參數(shù)由CATransaction來決定嘹屯,顯式創(chuàng)建CATransaction常常被用于關(guān)閉隱式動畫(獨立的CALayer對象默認開啟隱式動畫攻询,需要手動關(guān)閉)和調(diào)整動畫的時間。
Core Animation的動畫執(zhí)行過程都是在后臺操作的州弟,不會阻塞主線程钧栖。Core Animation是直接作用在CALayer上的,并非UIView婆翔。

CAAnimation注意要點:

  • 能用的動畫類只有4個子類:CABasicAnimation拯杠、CAKeyframeAnimation、CATransition啃奴、CAAnimationGroup潭陪;
  • CAMediaTiming是一個協(xié)議(protocol),CAMediaTiming媒體時間類協(xié)議解析:
    1.beginTime 動畫開始的時間默認為0最蕾;
    2.duration 動畫的持續(xù)時間依溯,默認為0 ,持續(xù)時間受速度的影響 實際動畫完成時間 = 持續(xù)時間/速度瘟则;
    3.speed 動畫的播放速度 黎炉,默認為1 ,速度設(shè)置為0 醋拧,可以暫停動畫慷嗜。如果speed=2 , duration =60 那么動畫真正播放完成的時間 30秒丹壕;
    4.timeOffset 動畫播放時間的偏移量庆械;
    5.
    repeatCount
    動畫的循環(huán)次數(shù) 默認是0 只播放一次;
    6.repeatDuration 動畫循環(huán)的持續(xù)時間雀费,
    repeatCount/repeatDuration 只能設(shè)置其中的一個屬性干奢;
    7.autoreverses 是否以動畫的形式返回 返回到播放之前的狀態(tài);
    8.fillMode 動畫填充模式,設(shè)置當(dāng)前對象在非活動時間段的狀態(tài)盏袄,
    要想fillMode有效 需設(shè)置removedOnCompletion = NO忿峻;
kCAFillModeForwards 當(dāng)動畫結(jié)束后薄啥,layer會一直保持著動畫最后的狀態(tài)
kCAFillModeBackwards 立即進入動畫的初始狀態(tài)并等待動畫開始
kCAFillModeBoth 動畫加入后開始之前 layer處于動畫初始狀態(tài) 動畫結(jié)束后layer保持動畫最后的狀態(tài)
kCAFillModeRemoved 默認值 動畫結(jié)束后 layer會恢復(fù)到之前的狀態(tài)

CAAnimation動畫屬性方法介紹:

  • 初始化的方法 animation
  • timingFunction 速度控制函數(shù),控制動畫運行的節(jié)奏
    timingFunction的初始化方法: functionWithName:
kCAMediaTimingFunctionLinear        線性,勻速
kCAMediaTimingFunctionEaseIn        慢進后快
kCAMediaTimingFunctionEaseOut       快進后慢
kCAMediaTimingFunctionEaseInEaseOut 先慢進后快再慢出 
kCAMediaTimingFunctionDefault       實際效果是動畫中間比較快
  • removedOnCompletion 完成動畫的時候 是否移除動畫效果 默認為YES
  • 代理方法:
-(void)animationDidStart:(CAAnimation *)anim
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag

CAAnimation子類:

繼承關(guān)系.png

  • CAAnaimation和CAPropertyAnimation是個抽象類逛尚,不具備動畫效 果垄惧,必須用它們的子類才有動畫效果;
  • CABasicAnimation基本動畫,做一些簡單效果绰寞;
  • CAKeyframeAnimation幀動畫到逊,做一些連續(xù)的流暢的動畫;
  • CAAnimationGroup是個動畫組滤钱,可以同時進行縮放觉壶,旋轉(zhuǎn)。
  • CATransition是轉(zhuǎn)場動畫件缸,界面之間跳轉(zhuǎn)都可以用轉(zhuǎn)場動畫铜靶。

1. CABasicAnimation 基礎(chǔ)動畫
CABasicAnimation用來創(chuàng)建基于兩個狀態(tài)的動畫,你只需要給出兩個狀態(tài)他炊,一個初始狀態(tài)一個終止?fàn)顟B(tài)争剿,系統(tǒng)自動為你將中間的動畫補全。
通過設(shè)定起始點痊末,終點蚕苇,時間,動畫會沿著你這設(shè)定點進行移動凿叠∩裕可以看做特殊的CAKeyFrameAnimation.
CABasicAnimation動畫主要是設(shè)置某個動畫屬性的初始值fromValue和結(jié)束值toValue,來產(chǎn)生動畫效果盒件。
創(chuàng)建CABasicAnimation 的方法辆它,但是在最新的apple開發(fā)文檔沒有查到path到底有哪些,網(wǎng)上搜羅了一下履恩,并猜測path跟layer中的屬性字段是一致的如background。

基于CAPropertyAnimation的屬性動畫呢蔫,可以更改屬性切心,二級屬性也可以去做動畫。

| path | 用途
| -------------
| rotaion.x | 旋轉(zhuǎn)片吊,弧度绽昏,X軸
| rotaion.y | 旋轉(zhuǎn),弧度俏脊,Y軸
| rotaion.z | 旋轉(zhuǎn)全谤,弧度,Z軸
| rotaion | 旋轉(zhuǎn)爷贫,弧度认然,Z軸补憾,完全等同于rotation.z
| scale.x | 縮放,X軸
| scale.y | 縮放卷员,Y軸
| scale.z | 縮放盈匾,Z軸
| scale | 縮放,XYZ軸
| translation.x | 移動毕骡,X軸
| translation.y | 移動削饵,Y軸
| translation.z | 移動,Z軸
| translation | 移動未巫,XY軸窿撬,value值為NSSize或者CGSize類型
| opacity等 | zPosition、frame叙凡、backgroundColor劈伴、cornerRadius類似的layer中的各種屬性

Animation的幾個屬性:
animationWithKeyPath:動畫的創(chuàng)建使用animationWithKeyPath: 因為使用的keyPath所以動畫屬性或者其結(jié)構(gòu)體中元素都可以產(chǎn)生動畫;
duration: 動畫的時長;
fromValue和toValue: 是CABasicAnimation的屬性,都是id類型的狭姨,所以要將基本類型包裝成對象;
removedOnCompletion: 決定動畫執(zhí)行完之后是否將該動畫的影響移除宰啦,默認是YES,則layer回到動畫前的狀態(tài);是否在播放完成后移除。這是一個非常重要的屬性饼拍,有的時候我們希望動畫播放完成赡模,但是保留最終的播放效果是,這個屬性一定要改為NO师抄,否則無效漓柑。
fillMode: 是個枚舉值(四種),當(dāng)removedOnCompletion設(shè)置為NO之后才會起作用叨吮×静迹可以設(shè)置layer是保持動畫開始前的狀態(tài)還是動畫結(jié)束后的狀態(tài),或是其他的;
autoreverses: 表示動畫結(jié)束后是否 backwards(回退) 到動畫開始前的狀態(tài)茶鉴》媪幔可與上面兩個屬性組合出不同效果。
timingFunction: 動畫的運動是勻速線性的還是先快后慢等涵叮,類似UIView動畫的opitions惭蹂。另外,CAMediaTimingFunction 方法可以自定義割粮。
delegate 代理:兩個動畫代理方法:

- (void)animationDidStart:(CAAnimation *)anim; 
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;

添加/移除動畫方法

給某個layer添加動畫
- (void)addAnimation:(CAAnimation *)anim forKey:(nullable NSString *)key; 
與之對應(yīng)的移除某個動畫是
- (void)removeAnimationForKey:(NSString *)key;
#pragma mark - CABasicAnimation-基礎(chǔ)動畫:位移盾碗、透明度、縮放舀瓢、旋轉(zhuǎn)
/**
 *  透明度動畫
 */
-(void)opacityAniamtion{
    CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"opacity"];
    //fromValue和toValue都是id類型的廷雅,所以要將基本類型包裝成對象
    anima.fromValue = [NSNumber numberWithFloat:1.0f];
    anima.toValue = [NSNumber numberWithFloat:0.2f];
    anima.duration = 1.0f; //動畫的時長
    //決定動畫執(zhí)行完之后是否將該動畫的影響移除,默認是YES,則layer回到動畫前的狀態(tài)
    anima.removedOnCompletion = NO;
    //是個枚舉值(四種),當(dāng)removedOnCompletion設(shè)置為NO之后才會起作用航缀∩碳埽可以設(shè)置layer是保持動畫開始前的狀態(tài)還是動畫結(jié)束后的狀態(tài),或是其他的
    anima.fillMode = kCAFillModeForwards;
    //表示動畫結(jié)束后是否 backwards(回退) 到動畫開始前的狀態(tài)谬盐〉樗剑可與上面兩個屬性組合出不同效果窝趣。
    //anima.autoreverses = YES;
    //動畫的運動是勻速線性的還是先快后慢等症脂,類似UIView動畫的opitions。另外型檀,CAMediaTimingFunction 方法可以自定義砸烦。
    anima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    anima.delegate = self;//設(shè)置代理弃鸦,可以檢測動畫的開始和結(jié)束
    [self.testView.layer addAnimation:anima forKey:@"opacityAniamtion"];
}
/**
 *  縮放動畫
 */
-(void)scaleAnimation{
    CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"transform.scale"];//同上
    anima.toValue = [NSNumber numberWithFloat:2.0f];
    anima.duration = 1.0f;
    anima.removedOnCompletion = NO;
    anima.fillMode = kCAFillModeForwards;
    [self.testView.layer addAnimation:anima forKey:@"scaleAnimation"];
}

/**
 *  旋轉(zhuǎn)動畫
 */
-(void)rotateAnimation{
    CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];//繞著z軸為矢量,進行旋轉(zhuǎn)(@"transform.rotation.z"==@@"transform.rotation")
    anima.toValue = [NSNumber numberWithFloat:3*M_PI];
    anima.duration = 1.0f;
    [self.testView.layer addAnimation:anima forKey:@"rotateAnimation"];
}
/**
 *  背景色變化動畫
 */
-(void)backgroundAnimation{
    CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
    anima.toValue =(id) [UIColor greenColor].CGColor;
    anima.duration = 1.0f;
    [self.testView.layer addAnimation:anima forKey:@"backgroundAnimation"];
}

2. CAKeyframeAnimation 關(guān)鍵幀動畫
Keyframe顧名思義就是關(guān)鍵點的frame幢痘,你可以通過設(shè)定CALayer的始點唬格、中間關(guān)鍵點、終點的frame颜说,時間购岗,動畫會沿你設(shè)定的軌跡進行移動 CAKeyframeAnimation 的一些比較重要的屬性。所以CAKeyframeAnimation也是根據(jù)屬性展示動畫的门粪,他與CABasicAnimation的不同點在于他可以指定多個狀態(tài)喊积,不局限于始末狀態(tài),這樣你的動畫將更加靈活玄妈。
CAKeyframeAnimation我們一般稱為關(guān)鍵幀動畫乾吻,主要是利用其values屬性,設(shè)置多個關(guān)鍵幀屬性值拟蜻,來產(chǎn)生動畫绎签。
對比UIView動畫跟關(guān)鍵幀動畫,關(guān)鍵幀動畫引入了動畫占比時長的概念酝锅,這讓我們能控制每個關(guān)鍵幀動畫的占用比例而不是傳入一個無意義的動畫時長 —— 這讓我們的代碼更加難以理解诡必。當(dāng)然,除了動畫占比之外搔扁,關(guān)鍵幀動畫的options參數(shù)也讓動畫變得更加平滑擒权。

2.1. path
這是一個 CGPathRef 對象,默認是空的阁谆,當(dāng)我們創(chuàng)建好CAKeyframeAnimation的實例的時候,可以通過制定一個自己定義的path來讓某一個物體按照這個路徑進行動畫愉老。這個值默認是nil场绿,當(dāng)其被設(shè)定的時候values 這個屬性就被覆蓋。

/**
 *  path動畫
 */
-(void)pathAnimation{
    CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2-100, 200, 200)];
    anima.path = path.CGPath;
    anima.duration = 2.0f;
    anima.removedOnCompletion = NO;
    anima.fillMode = kCAFillModeForwards;
    [_demoView.layer addAnimation:anima forKey:@"pathAnimation"];
}

2.2. values
一個數(shù)組嫉入,提供了一組關(guān)鍵幀的值焰盗,當(dāng)使用path的 時候 values的值自動被忽略璧尸。

-(void)keyframeAnimation{
    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    keyAnimation.duration = 1.0f;
  //CAAnimation類的屬性,可以設(shè)置動畫延遲多久執(zhí)行熬拒,示例代碼是延遲1秒執(zhí)行爷光。
    keyAnimation.beginTime = CACurrentMediaTime() + 1.0;
    
    CATransform3D transform1 = CATransform3DMakeScale(1.5, 1.5, 0);
    CATransform3D transform2 = CATransform3DMakeScale(0.8, 0.8, 0);
    CATransform3D transform3 = CATransform3DMakeScale(3, 3, 0);
    //是CAKeyframeAnimation的屬性,設(shè)置keyPath屬性在幾個關(guān)鍵幀的值澎粟,也是id類型的蛀序。
    keyAnimation.values = @[[NSValue valueWithCATransform3D:transform1],[NSValue valueWithCATransform3D:transform2],[NSValue valueWithCATransform3D:transform3]];
    //是CAKeyframeAnimation的屬性,每個值對應(yīng)相應(yīng)關(guān)鍵幀的時間比例值活烙。keyTimes屬性指定的是當(dāng)前狀態(tài)節(jié)點到初始狀態(tài)節(jié)點的時間占動畫總時長的比例徐裸。若果不設(shè)置keyTimes則勻速播放
    keyAnimation.keyTimes = @[@0,@0.5,@1];
    //是CAKeyframeAnimation的屬性,對應(yīng)每個動畫段的動畫過渡情況啸盏;而timingFunction是CAAnimation的屬性重贺。
    keyAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    keyAnimation.removedOnCompletion = NO;
    keyAnimation.fillMode = kCAFillModeForwards;
    [self.testView.layer addAnimation:keyAnimation forKey:nil];
}

3. CAAnimationGroup 組合動畫
Group也就是組合的意思,可以保存一組動畫對象,CAAnimationGroup的animations中可以放其他任何動畫類(包括CAAnimationGroup)回懦,將CAAnimationGroup對象加入圖層后气笙,組中所有動畫對象可以同時并發(fā)運行。
animations屬性:用來保存一組動畫對象的NSArray
注意:

  • animations里的單個動畫怯晕,當(dāng)單個動畫設(shè)置了duration之后動畫可能會有不同潜圃,一般里面不設(shè)置,在最外層設(shè)置group的duration即可贫贝。
  • 默認情況下秉犹,一個layer設(shè)定了很多動畫,他們都會同時執(zhí)行稚晚,而且是順序執(zhí)行崇堵,也可以通過設(shè)置動畫對象的beginTime屬性來更改動畫的開始時間
-(void)groupAnimation1{
//    //位移動畫
  CAKeyframeAnimation *anima1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
  NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];
  NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)];
  NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)];
  NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)];
  NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)];
  NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)];
  anima1.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];

  //縮放動畫
  CABasicAnimation *anima2 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
  anima2.fromValue = [NSNumber numberWithFloat:0.8f];
  anima2.toValue = [NSNumber numberWithFloat:2.0f];

  //旋轉(zhuǎn)動畫
  CABasicAnimation *anima3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
  anima3.toValue = [NSNumber numberWithFloat:M_PI*4];

  //組動畫
  CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
  groupAnimation.animations = [NSArray arrayWithObjects:anima1,anima2,anima3, nil];
  groupAnimation.duration = 4.0f;

  [_demoView.layer addAnimation:groupAnimation forKey:@"groupAnimation"];
  }

4. CATransition 系統(tǒng)封裝的過渡動畫
CATransition動畫就是動畫效果和方向的結(jié)合,以下為重要屬性
type:動畫過渡類型
Apple 官方的SDK其實只提供了四種過渡效果客燕,都支持方向設(shè)置:

kCATransitionFade 淡出效果
kCATransitionMoveIn 新視圖移動到舊視圖上
kCATransitionPush 新視圖推出舊視圖
kCATransitionReveal 移開舊視圖顯示新視圖

私有API提供了其他很多非常炫的過渡動畫鸳劳,其中部分支持方向設(shè)置,比如:

@"cube":立方體翻轉(zhuǎn)效果
@"suckEffect":收縮效果
@"oglFlip":翻轉(zhuǎn)效果
@"rippleEffect":水滴波紋效果
@"pageCurl":向上翻頁效果
@"pageUnCurl":向下翻頁效果
@"cameraIrisHollowOpen":攝像頭打開效果
@"cameraIrisHollowClose":攝像頭關(guān)閉效果

注意:私有api也搓,不建議開發(fā)者們使用赏廓。因為蘋果公司不提供維護,并且有可能造成你的app審核不通過傍妒。

subtype:動畫過渡方向

kCATransitionFromRight 從右側(cè)進入
kCATransitionFromLeft 從左側(cè)進入
kCATransitionFromTop 從頂部進入
kCATransitionFromBottom 從底部進入
startProgress:動畫起點(在整體動畫的百分比)
endProgress:動畫終點(在整體動畫的百分比)

寫法一

#pragma mark - CATransition:轉(zhuǎn)場動畫:淡入淡出幔摸、推擠、解開颤练、覆蓋
-(void)transitionAnimation
{
    /*
     什么是轉(zhuǎn)場動畫既忆?
     就是從一個場景轉(zhuǎn)換到另外一個場景,像導(dǎo)航控制器的push效果,就是一個轉(zhuǎn)場患雇。能為層提供移除屏幕和移入屏幕的動畫效果
     
     CATransition通常用于通過CALayer控制UIView內(nèi)子控件的過渡動畫跃脊,比如刪除子控件,添加子控件苛吱,切換兩個子控件等酪术。
     
     imageView切換圖片,控制器的push或modal翠储,UIView對象調(diào)用exchangeSubviewAtIndex:WithIndex:方法的時候可以出發(fā)轉(zhuǎn)場動畫.
     
     
     基本使用
     
     創(chuàng)建CATransition對象绘雁。
     為CATransition設(shè)置type和subtype兩個屬性,type指定動畫類型彰亥,subtype指定動畫移動方向(有些動畫是固定方向咧七,指定subtype無效)。
     如果不需要動畫執(zhí)行整個過程(動畫執(zhí)行到中間部分就停止)任斋,可以指定startProgress继阻,endProgress屬性。
     調(diào)用UIView的layer屬性的addAnimation: forKey:方法控制該UIView內(nèi)子控件的過渡動畫废酷。
     
     
     
     動畫類型:
     
     CATransition的type有以下幾個值
     kCATransitionFade 漸變
     kCATransitionMoveIn 覆蓋
     kCATransitionPush 推出
     kCATransitionReveal 揭開
     
     除此之外瘟檩,該type還支持如下私有動畫
     cube 立方體旋轉(zhuǎn)
     suckEffect  收縮動畫
     oglFlip  翻轉(zhuǎn)
     rippleEffect  水波動畫
     pageCurl  頁面揭開
     pageUnCurl 放下頁面
     cemeraIrisHollowOpen  鏡頭打開
     cameraIrisHollowClose 鏡頭關(guān)閉
     
     
     CATransition的subtype屬性用于控制動畫方向,支持如下值
     kCATransitionFromRight
     kCATransitionFromLeft
     kCATransitionFromTop
     kCATransitionFromBottom
     
     */
    
    //創(chuàng)建一個轉(zhuǎn)場動畫
    CATransition *animation = [CATransition animation];
    animation.beginTime = CACurrentMediaTime() + 1.0;

    animation.duration = 5;
    //設(shè)置轉(zhuǎn)場類型
    //animation.type = kCATransitionMoveIn;
    animation.type = @"oglFlip";

    //設(shè)置轉(zhuǎn)場的方向
    animation.subtype = kCATransitionFromTop;
    //設(shè)置動畫開始的位置
    //animation.startProgress = 0.5;
    //設(shè)置動畫結(jié)束的位置
    //animation.endProgress = 0.8;
    
    UIImage *image = [UIImage imageNamed:@"maskImage"];
    self.imageview.image = image;
    
    //添加動畫
    [self.imageview.layer addAnimation:animation forKey:@"transitionAnimation"];

}

寫法二

-(void)test
{
  [UIView beginAnimations:@"animationID" context:nil];
  [UIView setAnimationDuration:0.5f]; //動畫時長
  [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
  [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES]; //給視圖添加過渡效果
//在這里寫你的代碼.
  [UIView commitAnimations]; //提交動畫
}
#pragma UIView實現(xiàn)動畫
- (void) animationWithView : (UIView *)view WithAnimationTransition : (UIViewAnimationTransition) transition
{
    [UIView animateWithDuration:DURATION animations:^{
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        [UIView setAnimationTransition:transition forView:view cache:YES];
    }];
}
3. 自定義轉(zhuǎn)場動畫

非交互式的轉(zhuǎn)場動畫
目前為止澈蟆,官方支持以下幾種方式的自定義轉(zhuǎn)場:
在 UINavigationController 中 push 和 pop;
在 UITabBarController 中切換 Tab;
Modal 轉(zhuǎn)場:presentation 和 dismissal墨辛,俗稱視圖控制器的模態(tài)顯示和消失,僅限于modalPresentationStyle屬性為 UIModalPresentationFullScreen 或 UIModalPresentationCustom 這兩種模式;
UICollectionViewController 的布局轉(zhuǎn)場:UICollectionViewController 與 UINavigationController 結(jié)合的轉(zhuǎn)場方式趴俘,實現(xiàn)很簡單睹簇。
轉(zhuǎn)場代理(Transition Delegate)
這個協(xié)議要求我們實現(xiàn)兩個方法,其中一個定義了動畫的持續(xù)時間:
另一個方法描述整個動畫的執(zhí)行效果:
方法中獲取 transition context寥闪,從 transition context 中得到了需要做轉(zhuǎn)場的兩個 view controller太惠,然后可以使用最簡單的 UIView animation 來實現(xiàn)轉(zhuǎn)場動畫

交互式的轉(zhuǎn)場動畫

4. UIDynamicAnimator彈簧動畫
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市疲憋,隨后出現(xiàn)的幾起案子凿渊,更是在濱河造成了極大的恐慌,老刑警劉巖缚柳,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件埃脏,死亡現(xiàn)場離奇詭異,居然都是意外死亡秋忙,警方通過查閱死者的電腦和手機彩掐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灰追,“玉大人堵幽,你說我怎么就攤上這事旁壮。” “怎么了谐檀?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長裁奇。 經(jīng)常有香客問我桐猬,道長,這世上最難降的妖魔是什么刽肠? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任溃肪,我火速辦了婚禮,結(jié)果婚禮上音五,老公的妹妹穿的比我還像新娘惫撰。我一直安慰自己,他們只是感情好躺涝,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布厨钻。 她就那樣靜靜地躺著,像睡著了一般坚嗜。 火紅的嫁衣襯著肌膚如雪夯膀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天苍蔬,我揣著相機與錄音诱建,去河邊找鬼。 笑死碟绑,一個胖子當(dāng)著我的面吹牛俺猿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播格仲,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼押袍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了抓狭?” 一聲冷哼從身側(cè)響起伯病,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎否过,沒想到半個月后午笛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡苗桂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年药磺,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片煤伟。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡癌佩,死狀恐怖木缝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情围辙,我是刑警寧澤我碟,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站姚建,受9級特大地震影響矫俺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掸冤,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一厘托、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧稿湿,春花似錦铅匹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至策精,卻和暖如春舰始,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背咽袜。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工丸卷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人询刹。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓谜嫉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親凹联。 傳聞我的和親對象是個殘疾皇子沐兰,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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

  • 在iOS中隨處都可以看到絢麗的動畫效果,實現(xiàn)這些動畫的過程并不復(fù)雜蔽挠,今天將帶大家一窺ios動畫全貌住闯。在這里你可以看...
    每天刷兩次牙閱讀 8,488評論 6 30
  • 在iOS實際開發(fā)中常用的動畫無非是以下四種:UIView動畫,核心動畫澳淑,幀動畫比原,自定義轉(zhuǎn)場動畫。 1.UIView...
    請叫我周小帥閱讀 3,094評論 1 23
  • 在iOS中隨處都可以看到絢麗的動畫效果杠巡,實現(xiàn)這些動畫的過程并不復(fù)雜量窘,今天將帶大家一窺iOS動畫全貌。在這里你可以看...
    F麥子閱讀 5,110評論 5 13
  • 一氢拥、UIKit動畫 第一種寫法是利用屬性蚌铜,結(jié)合beginAnimations锨侯、commitAnimations 第...
    Gary_Tseng閱讀 965評論 1 3
  • 先看看CAAnimation動畫的繼承結(jié)構(gòu) CAAnimation{ CAPropertyAnimation { ...
    時間不會倒著走閱讀 1,649評論 0 1