iOS常用動(dòng)畫內(nèi)容以及原理

最近在做iOS界面轉(zhuǎn)場的動(dòng)畫,寫完轉(zhuǎn)場入口后基本元素還是回歸到我們常用的基本動(dòng)畫代碼诀姚,有關(guān)動(dòng)畫的帖子網(wǎng)絡(luò)上一搜一大把擎浴,而且介紹的都比較不錯(cuò)伦吠,本文還是不厭其煩的對(duì)基本常用到的動(dòng)畫做一個(gè)詳細(xì)統(tǒng)一介紹和總結(jié),主要記錄下自己學(xué)習(xí)動(dòng)畫的點(diǎn)惹骂。

App開發(fā)中幾乎都使用過動(dòng)畫苏携,絢麗的動(dòng)畫效果也是iOS系統(tǒng)的一大亮點(diǎn);使用動(dòng)畫可以讓我們的App非常炫酷对粪,同時(shí)更重要的是大大的提升了用戶體驗(yàn)右冻。那動(dòng)畫是什么呢?動(dòng)畫實(shí)質(zhì)其實(shí)就是一張張連續(xù)的圖片在一定的時(shí)間內(nèi)連續(xù)展示出來的效果著拭。打個(gè)比方說:把很多張慢動(dòng)作的武打戲圖片連續(xù)播放合成一段小視頻纱扭。動(dòng)畫就是和這個(gè)視頻是一樣的效果!實(shí)質(zhì)就是產(chǎn)生連續(xù)的假象來欺騙人的眼睛儡遮,從而達(dá)到動(dòng)畫的效果乳蛾!

iOS開發(fā)中,常用的動(dòng)畫有UIView動(dòng)畫核心動(dòng)畫鄙币,很多書籍上有區(qū)分隱式動(dòng)畫顯示動(dòng)畫以及其他動(dòng)畫的詳細(xì)介紹肃叶,下文中會(huì)簡單講到,如需要詳細(xì)介紹的可以去查找下相關(guān)資料十嘿。UIView動(dòng)畫核心動(dòng)畫一圖是iOS提供的動(dòng)畫API框架結(jié)構(gòu)因惭,UIView動(dòng)畫:UIKit / AppKit;核心動(dòng)畫包括:CATransaction動(dòng)畫以及Core Animation等框架绩衷,Core Animation等框架位于UIKit的下一層蹦魔,相比UIView的動(dòng)畫,它可以實(shí)現(xiàn)更復(fù)雜的動(dòng)畫效果唇聘。下面我們先來介紹下iOS中簡單常用的UIView動(dòng)畫的內(nèi)容及其使用版姑。

UIView動(dòng)畫和核心動(dòng)畫

Tip:在模擬器上運(yùn)行時(shí)柱搜,我們可以點(diǎn)擊菜單欄Debug下的Slow Animation或者快捷鍵command+T迟郎,來放慢App中的動(dòng)畫效果并分析動(dòng)畫內(nèi)容。

一聪蘸、UIView類實(shí)現(xiàn)的常用動(dòng)畫方法

對(duì)于每一個(gè)UIView都有一個(gè)Layer屬性宪肖,把這個(gè)Layer且稱作為RootLayer表制,而不是UIViewRootLayer的叫做非RootLayer。我們對(duì)UIView的屬性修改時(shí)時(shí)不會(huì)產(chǎn)生默認(rèn)動(dòng)畫控乾,而對(duì)非RootLayer屬性直接修改會(huì)產(chǎn)生動(dòng)畫么介,這個(gè)默認(rèn)動(dòng)畫的時(shí)間缺省值是0.25s,這個(gè)動(dòng)畫也稱作隱式動(dòng)畫蜕衡。UIView默認(rèn)情況下禁止了RootLayer的隱式動(dòng)畫壤短,但是在UIVIewanimation block方法中又重新啟用了它們。(有關(guān)UIViewCALayer介紹稍后詳說)

需要注意的是:使用UIView的動(dòng)畫方法慨仿,只能針對(duì)動(dòng)畫屬性修改才能產(chǎn)生動(dòng)畫效果久脯。UIView支持的動(dòng)畫屬性有framebounds镰吆、center帘撰、transformalpha万皿、backgroundColor摧找、contentStretch等。

第一種:使用UIView的 [beginAnimations … commitAniamtions] 模式來實(shí)現(xiàn)動(dòng)畫

先過一遍系統(tǒng)的API方法:

//開始動(dòng)畫
+ (void)beginAnimations:(NSString *)animationID context:(void *)context;

//提交動(dòng)畫
+ (void)commitAnimations;

//設(shè)置動(dòng)畫代理對(duì)象
+ (void)setAnimationDelegate:(id)delegate;

//當(dāng)動(dòng)畫即將開始時(shí)執(zhí)行指定的SEL方法《必須要先設(shè)置動(dòng)畫代理》
+ (void)setAnimationWillStartSelector:(SEL)selector

//當(dāng)動(dòng)畫結(jié)束時(shí)執(zhí)行指定的SEL方法《必須要先設(shè)置動(dòng)畫代理》
+ (void)setAnimationDidStopSelector:(SEL)selector;

//設(shè)置動(dòng)畫的持續(xù)時(shí)間牢硅,單位為:秒
+ (void)setAnimationDuration:(NSTimeInterval)duration;

//設(shè)置動(dòng)畫延遲執(zhí)行蹬耘,單位為:秒
+ (void)setAnimationDelay:(NSTimeInterval)delay;

//動(dòng)畫的開始時(shí)間,默認(rèn)為:立即
+ (void)setAnimationStartDate:(NSDate *)startDate;

//動(dòng)畫的速度曲線控制
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve;

//動(dòng)畫的重復(fù)次數(shù)
+ (void)setAnimationRepeatCount:(float)repeatCount;

//如果設(shè)置為YES,代表動(dòng)畫每次重復(fù)執(zhí)行的效果會(huì)跟上一次相反
+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses;

//設(shè)置視圖view的過渡效果减余,transition指定過渡類型婆赠,cache設(shè)置YES代表使用視圖緩存,性能較好
+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache;

//當(dāng)設(shè)置的時(shí)候忽視所有屬性的改變
+ (void)setAnimationsEnabled:(BOOL)enabled;

這種動(dòng)畫的使用方法比較簡單佳励,將動(dòng)畫代碼寫在begincommit之間就完成了動(dòng)畫的編寫

[UIView beginAnimations:@"animation" context:nil]; //準(zhǔn)備動(dòng)畫
// Code... 【在此處修改view的動(dòng)畫屬性休里,需注意:有些屬性不支持動(dòng)畫操作的】
[UIView commitAnimations]; //提交動(dòng)畫

我們舉個(gè)簡單的透明度漸變的例子:

//獲取當(dāng)前視圖的上下文,在此處傳入上下文可以在代理方法中使用到
CGContextRef context = UIGraphicsGetCurrentContext();  
//準(zhǔn)備編寫動(dòng)畫代碼
[UIView beginAnimations:@"AlphaAnimation" context:context];
[UIView setAnimationDuration:0.5f];
[animationView setAlpha:0.0f];
[UIView commitAnimations];

第二種:使用UIView的block代碼塊調(diào)用動(dòng)畫

在iOS4的時(shí)候蘋果大量的添加了Block API赃承,之前的動(dòng)畫API也不例外妙黍。使用動(dòng)畫的Block API后,方便了動(dòng)畫嵌套使用瞧剖,也讓我們的代碼更清晰拭嫁,使用也更簡單了!不多說了抓于,下面來介紹下Block的內(nèi)容做粤。
UIViewblock動(dòng)畫方法中常見的參數(shù)介紹:

duration   : 動(dòng)畫時(shí)長
delay      : 決定了動(dòng)畫在延遲多久之后執(zhí)行
options    : 用來決定動(dòng)畫的展示方式,參照下面的枚舉參數(shù)說明
animations : 具體動(dòng)畫內(nèi)容的代碼
completion : 動(dòng)畫結(jié)束后執(zhí)行的代碼塊

枚舉參數(shù)說明:

enum {
    //這部分是基礎(chǔ)屬性的設(shè)置   
    UIViewAnimationOptionLayoutSubviews            = 1 <<  0, //設(shè)置子視圖隨父視圖展示動(dòng)畫   
    UIViewAnimationOptionAllowUserInteraction      = 1 <<  1, //允許在動(dòng)畫執(zhí)行時(shí)用戶與其進(jìn)行交互   
    UIViewAnimationOptionBeginFromCurrentState     = 1 <<  2, //允許在動(dòng)畫執(zhí)行時(shí)執(zhí)行新的動(dòng)畫   
    UIViewAnimationOptionRepeat                    = 1 <<  3, //設(shè)置動(dòng)畫循環(huán)執(zhí)行   
    UIViewAnimationOptionAutoreverse               = 1 <<  4, //設(shè)置動(dòng)畫反向執(zhí)行捉撮,必須和重復(fù)執(zhí)行一起使用   
    UIViewAnimationOptionOverrideInheritedDuration = 1 <<  5, //強(qiáng)制動(dòng)畫使用內(nèi)層動(dòng)畫的時(shí)間值
    UIViewAnimationOptionOverrideInheritedCurve    = 1 <<  6, //強(qiáng)制動(dòng)畫使用內(nèi)層動(dòng)畫曲線值   
    UIViewAnimationOptionAllowAnimatedContent      = 1 <<  7, //設(shè)置動(dòng)畫視圖實(shí)時(shí)刷新
    UIViewAnimationOptionShowHideTransitionViews   = 1 <<  8, //設(shè)置視圖切換時(shí)隱藏怕品,而不是移除
    UIViewAnimationOptionOverrideInheritedOptions  = 1 <<  9, //   
    //這部分屬性設(shè)置動(dòng)畫播放的線性效果
    UIViewAnimationOptionCurveEaseInOut            = 0 << 16, //淡入淡出 首末減速   
    UIViewAnimationOptionCurveEaseIn               = 1 << 16, //淡入 初始減速   
    UIViewAnimationOptionCurveEaseOut              = 2 << 16, //淡出 末尾減速   
    UIViewAnimationOptionCurveLinear               = 3 << 16, //線性 勻速執(zhí)行
    //這部分設(shè)置UIView切換效果
    UIViewAnimationOptionTransitionNone            = 0 << 20,
    UIViewAnimationOptionTransitionFlipFromLeft    = 1 << 20, //從左邊切入   
    UIViewAnimationOptionTransitionFlipFromRight   = 2 << 20, //從右邊切入   
    UIViewAnimationOptionTransitionCurlUp          = 3 << 20, //從上面立體進(jìn)入   
    UIViewAnimationOptionTransitionCurlDown        = 4 << 20, //從下面立體進(jìn)入   
    UIViewAnimationOptionTransitionCrossDissolve   = 5 << 20, //溶解效果
    UIViewAnimationOptionTransitionFlipFromTop     = 6 << 20, //從上面切入   
    UIViewAnimationOptionTransitionFlipFromBottom  = 7 << 20, //從下面切入
};
注意:此類型可以使用“|”進(jìn)行多項(xiàng)一起使用

①、UIView實(shí)現(xiàn)的動(dòng)畫最常用普通的方法
系統(tǒng)API的說明和功能介紹:

//一般的動(dòng)畫
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOL finished))completion;
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void(^)(void))animations completion:(void(^)(BOOL finished))completion;
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void(^)(void))animations;

常用的動(dòng)畫使用也比較簡單巾遭,把之前寫在begincommit之間的代碼移動(dòng)到block中就完成動(dòng)畫編寫肉康,如:

[UIView animateWithDuration:4.0 // 動(dòng)畫時(shí)長
                      delay:2.0 // 動(dòng)畫延遲
                    options:UIViewAnimationOptionCurveEaseIn // 動(dòng)畫過渡效果
                 animations:^{ //code... 動(dòng)畫內(nèi)容 }
                 completion:^(BOOL finished) { //code... 動(dòng)畫完成后執(zhí)行 }];

同樣的闯估,還以透明度漸變?yōu)槔樱?/p>

[UIView animateWithDuration:0.5 // 動(dòng)畫時(shí)長
                      delay:0.0 // 動(dòng)畫延遲
                    options:UIViewAnimationOptionCurveEaseIn // 動(dòng)畫過渡效果
                 animations:^{ [animationView setAlpha:0.0f]; }
                 completion:^(BOOL finished) { //code... 動(dòng)畫完成后執(zhí)行 }];

②、UIView的轉(zhuǎn)場動(dòng)畫類方法
系統(tǒng)API的說明和功能介紹:

//轉(zhuǎn)場動(dòng)畫
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOL finished))completion;
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void(^)(BOOL finished))completion;
/*第二個(gè)方法調(diào)用完畢后吼和,還需要處理View的層次關(guān)系涨薪,添加toView到父視圖并移除fromView*/

轉(zhuǎn)場動(dòng)畫換個(gè)卡牌翻轉(zhuǎn)的例子,示例代碼如:

imageView.image = [UIImage imageNamed:@"背景圖片"];
[UIView transitionWithView:imageView 
                  duration:0.5 
                   options:UIViewAnimationOptionTransitionFlipFromLeft
                animations:^{ imageView.image = [UIImage imageNamed:@"內(nèi)容圖片"]; }
                completion:^(BOOL finished) { //code... 動(dòng)畫完成后執(zhí)行 }];

③炫乓、UIView的彈簧動(dòng)畫類方法(iOS 7后添加的API)
這個(gè)方法是iOS7之后的一個(gè)新方法刚夺,通過這個(gè)方法,可以方便的制作出彈簧振動(dòng)效果的動(dòng)畫末捣,這個(gè)方法的核心是兩個(gè)阻尼參數(shù)光督。
彈簧動(dòng)畫API的說明和功能介紹:

//彈簧的彈性動(dòng)畫(iOS7之后新加的方法)
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOL finished))completion;

動(dòng)畫方法中的新參數(shù):

usingSpringWithDamping : 取值范圍[0.0~1.0],數(shù)值越小振動(dòng)幅度越大 
initialSpringVelocity  : 初始速度塔粒,數(shù)值越大開始移動(dòng)越快

基本寫法及示例代碼:

[UIView animateWithDuration:4.0 // 動(dòng)畫時(shí)長                      
                      delay:0.0 // 動(dòng)畫延遲     
     usingSpringWithDamping:1.0 // 類似彈簧振動(dòng)效果 0~1      
      initialSpringVelocity:5.0 // 初始速度                    
                    options:UIViewAnimationOptionCurveEaseInOut // 動(dòng)畫過渡效果
                 animations:^{ // code... } 
                 completion:^(BOOL finished) { // code... }];

④结借、UIView的關(guān)鍵幀動(dòng)畫類方法(iOS 7后添加的API)
關(guān)鍵幀動(dòng)畫是指:給出整個(gè)動(dòng)畫過程中的幾個(gè)關(guān)鍵幀畫面信息,關(guān)鍵幀之間的過渡幀都由計(jì)算機(jī)自動(dòng)生成卒茬。
這個(gè)方法也是iOS7之后的一個(gè)新方法船老,通過這個(gè)方法可以不需要去使用到核心動(dòng)畫(Core Animation)就能創(chuàng)建關(guān)鍵幀的更多更復(fù)雜的動(dòng)畫效果。
關(guān)鍵幀動(dòng)畫API的說明和功能介紹:

//創(chuàng)建關(guān)鍵幀方法
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOL finished))completion;

//添加關(guān)鍵幀
+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void(^)(void))animations;

以簡單的單次抖動(dòng)作為示例:(這寫復(fù)雜了僅作參考)

    __weak UIView *weakView = self.animationView;
    void(^animations)(void) = ^{
        //向右旋轉(zhuǎn)
        void(^leftCallblock)(void) = ^{
            weakView.transform = CGAffineTransformRotate(weakView.transform,M_PI/9);
        };
        [UIView addKeyframeWithRelativeStartTime:0.0   //相對(duì)于6秒所開始的時(shí)間(第0秒開始動(dòng)畫)
                                relativeDuration:1/4.0 //相對(duì)于6秒動(dòng)畫的持續(xù)時(shí)間(動(dòng)畫持續(xù)2秒)
                                      animations:leftCallblock];
        
        //復(fù)原
        void(^resetblock)(void) = ^{
            weakView.transform = CGAffineTransformIdentity;
        };
        [UIView addKeyframeWithRelativeStartTime:1/4.0   //相對(duì)于6秒所開始的時(shí)間(第0秒開始動(dòng)畫)
                                relativeDuration:1/4.0 //相對(duì)于6秒動(dòng)畫的持續(xù)時(shí)間(動(dòng)畫持續(xù)2秒)
                                      animations:resetblock];
        
        //向左旋轉(zhuǎn)
        void(^rightCallblock)(void) = ^{
            weakView.transform = CGAffineTransformRotate(weakView.transform,-M_PI/9);
        };
        [UIView addKeyframeWithRelativeStartTime:2/4.0   //相對(duì)于6秒所開始的時(shí)間(第0秒開始動(dòng)畫)
                                relativeDuration:1/4.0 //相對(duì)于6秒動(dòng)畫的持續(xù)時(shí)間(動(dòng)畫持續(xù)2秒)
                                      animations:rightCallblock];
        
        //復(fù)原
        [UIView addKeyframeWithRelativeStartTime:3/4.0   //相對(duì)于6秒所開始的時(shí)間(第0秒開始動(dòng)畫)
                                relativeDuration:1/4.0 //相對(duì)于6秒動(dòng)畫的持續(xù)時(shí)間(動(dòng)畫持續(xù)2秒)
                                      animations:resetblock];
    };
    [UIView animateKeyframesWithDuration:0.5f
                                   delay:0.0f
                                 options:UIViewKeyframeAnimationOptionCalculationModeLinear
                              animations:animations
                              completion:NULL];

關(guān)鍵幀新加的枚舉參數(shù):

enum {
    UIViewKeyframeAnimationOptionCalculationModeLinear    = 0 << 10, // default 
    UIViewKeyframeAnimationOptionCalculationModeDiscrete  = 1 << 10,
    UIViewKeyframeAnimationOptionCalculationModePaced     = 2 << 10,
    UIViewKeyframeAnimationOptionCalculationModeCubic     = 3 << 10,
    UIViewKeyframeAnimationOptionCalculationModeCubicPaced = 4 << 10
};

這里的示例中使用到了transform屬性圃酵,額外再記錄下transform屬性
transform提供的API來說主要體現(xiàn)在縮放柳畔、位移和旋轉(zhuǎn)三個(gè)方面,transform的運(yùn)算是按照矩陣(3x3矩陣)進(jìn)行運(yùn)算的郭赐,這樣會(huì)減少運(yùn)算量薪韩,提高效率。
關(guān)于transform和矩陣的詳細(xì)內(nèi)容請(qǐng)參考:iOS開發(fā)筆記之transform

//用來連接兩個(gè)變換效果并返回捌锭。返回的t = t1 * t2
CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);

//矩陣初始值俘陷。[ 1 0 0 1 0 0 ]
CGAffineTransformIdentity;

//自定義矩陣變換,需要掌握矩陣變換的知識(shí)才知道怎么用观谦。參照上面推薦的原理鏈接
CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty);

/*
    旋轉(zhuǎn)視圖
        1.當(dāng)參數(shù)x>0 && x<=M_PI時(shí)拉盾,為順時(shí)針
        2.當(dāng)參數(shù)x>-M_PI && x<0時(shí),為逆時(shí)針
        3.若參數(shù)x<M_PI || x>2.0*M_PI時(shí)豁状,則旋轉(zhuǎn)方向等同于x%2的旋轉(zhuǎn)方向
    總結(jié):旋轉(zhuǎn)方向就是向最短路徑方向旋轉(zhuǎn)
*/
CGAffineTransformMakeRotation(CGFloat angle);
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle);
?
//縮放視圖捉偏。等同于CGAffineTransformScale(self.transform, sx, sy)
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy);
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy);

//平移視圖。等同于CGAffineTransformTranslate(self.transform, tx, ty)
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty);
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty);

二泻红、核心動(dòng)畫(Core Animation框架)

Core Animation框架是基于OpenGLCore Graphics圖像處理框架的一個(gè)跨平臺(tái)的動(dòng)畫框架夭禽。在真實(shí)的開發(fā)中,一般還是主要使用UIView封裝的動(dòng)畫谊路,而很少使用Core Animation的動(dòng)畫讹躯;使用UIViewCALayer都能實(shí)現(xiàn)動(dòng)畫效果,但是當(dāng)一般的UIView動(dòng)畫不能滿足我們的需求時(shí),就需要使用核心動(dòng)畫來實(shí)現(xiàn)蜀撑。核心動(dòng)畫是直接作用在CALayer上的動(dòng)畫,而非UIView對(duì)象剩彬;所以介紹核心動(dòng)畫前酷麦,我們先了解下UIViewCALayer之間的聯(lián)系以及區(qū)別。

關(guān)聯(lián)引申??????????
CALayer是屬于Core Animation部分的內(nèi)容喉恋,包含在QuartzCore框架中沃饶,這是一個(gè)跨平臺(tái)的框架,既可以用在iOS中又可以用在Mac OS X中轻黑;實(shí)際上CALayer只是捕獲App所提供的內(nèi)容糊肤,并緩存成bitmap(位圖),當(dāng)任何與CALayer關(guān)聯(lián)的屬性值發(fā)生變化時(shí)氓鄙,Core Animation就會(huì)將新的bitmap(位圖)傳給繪圖硬件馆揉,并根據(jù)新的bitmap(位圖)更新顯示。
UIViewiOS系統(tǒng)中界面元素的基礎(chǔ)抖拦,所有的界面元素都是繼承自UIView類还蹲,它真正的繪圖部分裸删,是由一個(gè)CALayer類來管理。每個(gè)UIView默認(rèn)就包含一個(gè)CALayer屬性,UIView就像是一個(gè)CALayer的管理器账蓉,在View顯示的時(shí)候,UIView做為CALayerCALayerDelegate傅瞻,UIView的顯示內(nèi)容由內(nèi)部的CALayer來顯示亲澡。訪問UIView的與繪圖和跟坐標(biāo)有關(guān)的屬性,例如frame凿菩、bounds等,實(shí)際上內(nèi)部都是在訪問它所包含的CALayer的相關(guān)屬性帜讲。有人說UIView就像一個(gè)畫板蓄髓,而layer就像畫布,一個(gè)畫板上可以有很多塊畫布舒帮,但是畫布不能有畫板会喝。

CALayerUIView類似都擁有自己的樹形結(jié)構(gòu),UIView包含很多subView玩郊,而CALayer是可以包含subLayer的肢执,因此形成了圖層樹,CALayer層是可以嵌套的译红,可以向它的layer上添加subLayer预茄,來完成某些特殊內(nèi)容的顯示。

UIViewCALayer的主要區(qū)別
1、UIView是可以響應(yīng)事件的耻陕,但是CALayer不能響應(yīng)事件
2拙徽、UIView主要負(fù)責(zé)管理顯示內(nèi)容,而CALayer主要負(fù)責(zé)渲染和呈現(xiàn)诗宣。如果沒有CALayer膘怕,我們是看不到內(nèi)容的。
3召庞、CALayer內(nèi)部維護(hù)著三分layer tree岛心,分別是presentLayer tree(動(dòng)畫樹),modeLayer tree(模型樹)篮灼,render tree(渲染樹)忘古,在做iOS動(dòng)畫的時(shí)候,我們修改動(dòng)畫的屬性诅诱,在動(dòng)畫的其實(shí)是CALayerpresent Layer的屬性值髓堪,而最終展示在界面上的其實(shí)是提供UIViewmodelLayer

CALayer核心動(dòng)畫與UIView動(dòng)畫的區(qū)別:
UIView封裝的動(dòng)畫執(zhí)行完畢之后不會(huì)反彈娘荡,CALayer核心動(dòng)畫則會(huì)旦袋;另外UIView的動(dòng)畫期間可以處理用戶事件,CALayer核心動(dòng)畫則不能它改。例如:如果是通過CALayer核心動(dòng)畫改變layer的位置狀態(tài)疤孕,表面上看雖然已經(jīng)改變了,但是實(shí)際上它的位置是沒有改變的央拖。

核心動(dòng)畫官方文檔地址:Core Animation Guide

核心動(dòng)畫是iOSOS X上的圖形渲染和動(dòng)畫基礎(chǔ)設(shè)施祭阀,用于為應(yīng)用程序的視圖和其他視覺元素設(shè)置動(dòng)畫。使用核心動(dòng)畫鲜戒,為您繪制每幅畫面所需的大部分工作专控。所有你需要做的是配置一些動(dòng)畫參數(shù)(如開始和結(jié)束點(diǎn)),并告訴核心動(dòng)畫開始遏餐。核心動(dòng)畫完成其余的工作伦腐,將大部分實(shí)際的繪圖工作交給板載圖形硬件,以加速渲染失都。這種自動(dòng)圖形加速可以實(shí)現(xiàn)高幀速率和平滑動(dòng)畫柏蘑,而不會(huì)對(duì)CPU造成負(fù)擔(dān),并減慢應(yīng)用程序的速度粹庞。

核心動(dòng)畫的繼承結(jié)構(gòu)

CAAnimation <CAMediaTiming> {
    CATransition
    CAAnimationGroup
    CAPropertyAnimation {
        CABasicAnimation {
            CASpringAnimation  (iOS 9才開始支持)
        }
        CAKeyframeAnimation
    }
}

核心動(dòng)畫的繼承關(guān)系與常用屬性如下圖


核心動(dòng)畫的繼承關(guān)系與常用屬性

CAAnimation是所有動(dòng)畫對(duì)象的父類咳焚,它遵守CAMediaTiming協(xié)議,負(fù)責(zé)控制動(dòng)畫的時(shí)間庞溜、速度和時(shí)間曲線等等革半,是一個(gè)抽象類,不能直接使用。CAPropertyAnimationCAAnimation的子類又官,它支持動(dòng)畫地顯示圖層的KeyPath延刘,也不能直接使用。
iOS9.0之后新增CASpringAnimation類六敬,它實(shí)現(xiàn)彈簧效果的動(dòng)畫是CABasicAnimation的子類碘赖。
綜上,核心動(dòng)畫類中可以直接使用的類有:CATransition觉阅、CABasicAnimation崖疤、CASpringAnimation秘车、CAKeyframeAnimation典勇、CAAnimationGroup五個(gè)類。
①叮趴、CAAnimation的屬性介紹:注意CAAnimation不能直接使用

//動(dòng)畫開始結(jié)束的回調(diào)代理
@property (nullable, assgin) id delegate;
//動(dòng)畫完成后是否移除動(dòng)畫割笙,默認(rèn)為YES
@property (getter=isRemovedOnCompletion) BOOL removedOnCompletion;
//動(dòng)畫的動(dòng)作規(guī)則,包含勻速眯亦、慢進(jìn)快出伤溉、快進(jìn)慢出、慢進(jìn)慢出<中間加速>妻率、默認(rèn)
@property (nullable, strong) CAMediaTimingFunction *timingFunction;

+ (id)animation;    //類方法創(chuàng)建動(dòng)畫對(duì)象

注意:
timingFunction 可通過系統(tǒng)提供的API自定義喜歡的曲線函數(shù)來處理動(dòng)畫
動(dòng)畫的removedOnCompletion屬性需要配合fillMode來使用乱顾。默認(rèn)為YES,fillMode不可用

CAAnimation的協(xié)議屬性介紹:

//開始時(shí)間宫静,例如:CACurrentMediaTime() + x 其中x為延遲時(shí)間
@property CFTimeInterval beginTime;
//動(dòng)畫執(zhí)行時(shí)間走净,與speed有關(guān)系,默認(rèn)為1.0孤里,如果speed=2.0伏伯,那么執(zhí)行時(shí)間為:durantion*(1.0/2.0)
@property CFTimeInterval duration;
//動(dòng)畫執(zhí)行速度
@property float speed;
//動(dòng)畫的時(shí)間延遲,默認(rèn)為0
@property CFTimeInterval timeOffset;
//重復(fù)執(zhí)行次數(shù)
@property float repeatCount;
//重復(fù)執(zhí)行時(shí)間捌袜,此屬性優(yōu)先級(jí)大于repeatCount
@property CFTimeInterval repeatDuration;
//是否自動(dòng)翻轉(zhuǎn)動(dòng)畫说搅,默認(rèn)為NO,如果為YES虏等,那么整個(gè)動(dòng)畫效果為A->B->A
@property BOOL autoreverses;
/*動(dòng)畫的填充方式弄唧,
動(dòng)畫結(jié)束后回到準(zhǔn)備狀態(tài)(kCAFillModeForwards)、
動(dòng)畫結(jié)束后保持最后狀態(tài)(kCAFillModeBackwards)霍衫、
動(dòng)畫結(jié)束后回到準(zhǔn)備狀態(tài)并保持最后狀態(tài)(kCAFillModelBoth)套才、
執(zhí)行完成移除動(dòng)畫(kCAFillModeRemoved)
*/
@property (copy) NSString *fillMode;

動(dòng)畫代理對(duì)象協(xié)議

//動(dòng)畫開始時(shí)回調(diào)此方法
- (void)animationDidStart:(CAAnimation *)animation;

//動(dòng)畫結(jié)束時(shí)回調(diào)此方法
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag;

②、CATransition轉(zhuǎn)場動(dòng)畫的使用
CATransition的屬性介紹:

@property (copy) NSString *type;  //轉(zhuǎn)場類型
@property (nullable, copy) NSString *subtype;  //轉(zhuǎn)場方向
@property float startProgress;  //開始進(jìn)度慕淡,默認(rèn)0.0背伴,如果為0.4則直接從0.4開始動(dòng)畫
@property float endProgress;  //結(jié)束進(jìn)度,默認(rèn)1.0,如果為0.6則直接到0.6結(jié)束動(dòng)畫
@property (nullable, strong) id filter;  //開始進(jìn)度

轉(zhuǎn)場類型有私有API非私有API兩種

可供type選擇的值有以下內(nèi)容(轉(zhuǎn)場類型)
{
    //公開API轉(zhuǎn)場種類
    kCATransitionFade      漸變
    kCATransitionMoveIn    覆蓋
    kCATransitionPush      推出
    kCATransitionReveal    揭開
    //私有API轉(zhuǎn)場種類
    @"cube"                      立方體翻轉(zhuǎn)效果
    @"oglFlip"                   翻轉(zhuǎn)效果
    @"suckEffect"                收縮效果傻寂,動(dòng)畫方向不可控
    @"rippleEffect"              水滴波紋效果息尺,動(dòng)畫方向不可控
    @"pageCurl"                  向上翻頁效果
    @"pageUnCurl"                向下翻頁效果
    @"cameralIrisHollowOpen"     攝像頭打開效果
    @"cameralIrisHollowClose"    攝像頭關(guān)閉效果
};

可供subtype選擇的值有以下內(nèi)容(轉(zhuǎn)場方向)
{
    kCATransitionFromRight     從右開始
    kCATransitionFromLeft      從左開始
    kCATransitionFromTop       從上開始
    kCATransitionFromBottom    從下開始
};

轉(zhuǎn)場動(dòng)畫的基本寫法及示例代碼:(以淡入淡出的動(dòng)畫效果為例)

CATransition *animation = [CATransition animation];
animation.type = kCATransitionFade;
animation.subType = kCATransitionFromLeft;
animation.duration = 0.5f;
self.imageView.image = [UIImage imageNamed:@"動(dòng)畫后的圖片"];
[self.imageView.layer addAnimation:animation forKey:@"transition"];

③、CAPropertyAnimation的子類CABasicAnimation的使用
CAPropertyAnimation的子類初始化方法

//通過key創(chuàng)建一個(gè)CAPropertyAnimation對(duì)象
+ (id)animationWithKeyPath:(NSString *)path;

注意:path可以設(shè)置動(dòng)畫的屬性列表
CATransform3D {
    旋轉(zhuǎn)
    rotation
    transform.rotation.x    
    transform.rotation.y
    transform.rotation.z
    縮放
    scale
    transform.scale.x        
    transform.scale.y
    transform.scale.z
    平移
    translation
    transform.translation.x    
    transform.translation.y
    transform.translation.z
}
CGPoint {
    position
    position.x
    position.y
}
CGRect {
    bounds
    bounds.size
    bounds.size.width
    bounds.size.height
    
    bounds.origin
    bounds.origin.x
    bounds.origin.y
}
property {
    opacity
    backgroundColor
    cornerRadius
    boarderWidth
    contents
    
    SHadow {
        shadowColor
        shadowOffset
        shadowOpacity
        shadowRadius
    }
}
注意:CAPropertyAnimation是抽象類疾掰,不能直接使用搂誉,只能使用子類

CABasicAnimation屬性介紹:

@property (nullable, strong) id fromValue;  //開始值
@property (nullable, strong) id toValue;    //結(jié)束值
@property (nullable, strong) id byValue;    //偏移值

CABasicAnimation屬性之間的規(guī)則:

1、fromValue和toValue不為空静檬,動(dòng)畫的效果會(huì)從fromValue的值變化到toValue
2炭懊、fromValue和byValue不為空,動(dòng)畫的效果將會(huì)從fromValue變化到fromValue+byValue
3拂檩、toValue和byValue都不為空侮腹,動(dòng)畫的效果將會(huì)從toValue-byValue變化到toValue
4、僅fromValue的值不為空稻励,動(dòng)畫的效果將會(huì)從fromValue的值變化到當(dāng)前的狀態(tài)
5父阻、僅toValue的值不為空,動(dòng)畫的效果將會(huì)從當(dāng)前狀態(tài)的值變化到toValue的值
6望抽、僅byValue的值不為空加矛,動(dòng)畫的效果將會(huì)從當(dāng)前的值變化到(當(dāng)前狀態(tài)的值+byValue)的值

CABasicAnimation動(dòng)畫的基本寫法及示例代碼:(以淡入淡出的動(dòng)畫效果為例)

CABasicAnimation *animation = nil;
animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
[animation setFromValue:@1.0];
[animation setToValue:@0.1];
[animation setDelegate:self];
[animation setDuration:0.25];
[animation setRemovedOnCompletion:NO];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[animation setAutoreverses:YES];
[animation setFillMode:kCAFillModeBoth];
[animationView.layer addAnimation:animation forKey:@"animation"];

④、CABasicAnimation的子類CASpringAnimation的使用
CASpringAnimation屬性介紹:

@property CGFloat mass;             //質(zhì)量煤篙,振幅與質(zhì)量成反比
@property CGFloat stiffness;        //剛度系數(shù)斟览,值越大,形變產(chǎn)生的力越大
@property CGFloat damping;          //阻尼系數(shù)辑奈,阻止彈簧伸縮的系數(shù)苛茂,值越大,停止越快
@property CGFloat initialVelocity;  //初始速率身害,速率為正數(shù)時(shí)速度與運(yùn)動(dòng)方向一致味悄,為負(fù)數(shù)時(shí),速度與運(yùn)動(dòng)方向相反
@property (readonly) CFTimeInterval settlingDuration;    //結(jié)算時(shí)間塌鸯,只讀侍瑟。返回彈簧動(dòng)畫到停止時(shí)的估算時(shí)間

CASpringAnimation動(dòng)畫的基本寫法及示例代碼:

CASpringAnimation *spring = [CASpringAnimation animationWithKeyPath:@"position.y"];
spring.damping = 5;
spring.stiffness = 100;
spring.mass = 1;
spring.initialVelocity = 0;
spring.duration = spring.settlingDuration;
spring.formValue = @(animationView.cemter.y);
spring.toValue = @(animationView.center.y+(button.selected?100:-100));
spring.fillMode = kCAFillModeForwards;
[animationView.layer addAnimation:spring forKey:@"spring"];

⑤、CAPropertyAnimation的子類CAKeyframeAnimation的使用
CAKeyframeAnimation屬性介紹:

//關(guān)鍵幀值數(shù)組丙猬,一組變化值
@property (nullable, copy) NSArray *values;
//關(guān)鍵幀幀路徑涨颜,優(yōu)先級(jí)比values高
@property (nullable) CGPathRef path;
//每一幀對(duì)應(yīng)的時(shí)間,可以用來控制速度茧球,它和每一幀對(duì)應(yīng)庭瑰,取值范圍:[0.0~1.0],不設(shè)置則默認(rèn)相等
@property (nullable, copy) NSArray *keyTimes;
//每一幀對(duì)應(yīng)的時(shí)間曲線函數(shù)抢埋,也就是每一幀的運(yùn)動(dòng)節(jié)奏
@property (nullable, copy) NSArray *timingFunctions;
//動(dòng)畫的計(jì)算模式
@property (copy) NSString *calculationMode;
//動(dòng)畫的張力
@property (nullable, copy) NSArray *tensionValues;
//動(dòng)畫的連續(xù)性值
@property (nullable, copy) NSArray *continuityValues;
//動(dòng)畫的偏斜率
@property (nullable, copy) NSArray *biasValues;
//動(dòng)畫沿路徑旋轉(zhuǎn)方式弹灭,默認(rèn)為nil
@property (nullable, copy) NSString *rotationMode;

//動(dòng)畫的計(jì)算模式有
enum {
  kCAAnimationLinear      //默認(rèn)值督暂,關(guān)鍵幀為座標(biāo)點(diǎn)的時(shí)候,關(guān)鍵幀之間直接直線相連進(jìn)行插值計(jì)算;
  kCAAnimationDiscrete    //離散的,也就是沒有補(bǔ)間動(dòng)畫
  kCAAnimationPaced       //平均
  kCAAnimationCubic       //對(duì)關(guān)鍵幀為座標(biāo)點(diǎn)的關(guān)鍵幀進(jìn)行圓滑曲線相連后插值計(jì)算
  kCAAnimationCubicPaced  //在kCAAnimationCubic的基礎(chǔ)上使得動(dòng)畫運(yùn)行變得均勻
};
注意:使用kCAAnimationPaced和kCAAnimationCubic以及kCAAnimationCubicPaced時(shí),keyTimes跟timeFunctions失效

//動(dòng)畫沿路徑旋轉(zhuǎn)方式
enum {
  kCAAnimationRotateAuto         //自動(dòng)旋轉(zhuǎn)
  kCAAnimationRotateAutoReverse  //自動(dòng)翻轉(zhuǎn)
};

CAKeyframeAnimation動(dòng)畫的基本寫法及示例代碼:

UIBezierPath *path = nil;
CAKeyframeAnimation *animation = nil;
path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 200, 100)];
animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
[animation setPath:path.CGPath];
[animation setDuration:0.5];
[animation setRemovedOnCompletion:NO];
[animation setFillMode:kCAFillModeBoth];
[animationView.layer addAnimation:animation forKey:nil];

⑥穷吮、CAAnimationGroup的使用
CAAnimationGroup屬性介紹:

//數(shù)組中存放CAAnimation的動(dòng)畫對(duì)象
@property (nullable, copy) NSArray *animations;

CAAnimationGroup動(dòng)畫的基本寫法及示例代碼:

CGMutablePathRef path = CGPathCreateMutable();    
CGPathAddEllipseInRect(path, NULL, CGRectMake(0, 0, 320, 320));
CAKeyframeAnimation *position = [CAKeyframeAnimation animationWithKeyPath:@"position"];
[position setPath:path];
[position setDuration:3];
[position setRemovedOnCompletion:NO];
[position setFillMode:kCAFillModeForwards]; 
CGPathRelease(path);

CABasicAnimation *alpha = [CABasicAnimation animationWithKeyPath:@"opacity"];
[alpha setDuration:1.0];
[alpha setRepeatCount:3];
[alpha setAutoreverses:YES];
[alpha setFromValue:@1.0];
[alpha setDelegate:self];
[animation setToValue:@0.1];

CAAnimationGroup *group = [CAAnimationGroup animation];
[group setDuration:3.0];
[group setAnimations:@[position,alpha]];
[animationView.layer addAnimation:group forKey:nil];

三逻翁、核心動(dòng)畫和UIView動(dòng)畫的對(duì)比

核心動(dòng)畫UIView動(dòng)畫的對(duì)比:UIView動(dòng)畫可以看成是對(duì)核心動(dòng)畫的封裝,和UIView動(dòng)畫不同的是捡鱼,通過核心動(dòng)畫改變layer的狀態(tài)(比如position)八回,動(dòng)畫執(zhí)行完畢后實(shí)際上是沒有改變的(表面上看起來已改變)。
view加上動(dòng)畫驾诈,本質(zhì)上是對(duì)其layer進(jìn)行操作缠诅,layer包含了各種支持動(dòng)畫的屬性,動(dòng)畫則包含了屬性變化的值乍迄、變化的速度管引、變化的時(shí)間等等,兩者結(jié)合產(chǎn)生動(dòng)畫的過程就乓。
總體來說核心動(dòng)畫的優(yōu)點(diǎn)有:
  - 性能強(qiáng)大汉匙,使用硬件加速拱烁,可以同時(shí)向多個(gè)圖層添加不同的動(dòng)畫效果
  - 接口易用生蚁,只需要少量的代碼就可以實(shí)現(xiàn)復(fù)雜的動(dòng)畫效果
  - 運(yùn)行在后臺(tái)線程中,在動(dòng)畫過程中響應(yīng)交互事件(UIView動(dòng)畫默認(rèn)動(dòng)畫過程中不響應(yīng)交互事件)

四戏自、CATransaction的使用

CATransaction顧名思義“事務(wù)”邦投,創(chuàng)建動(dòng)畫事務(wù)的目的是為了操作的原子性,它的目的就是能保證多個(gè)“動(dòng)畫屬性”的同時(shí)生效擅笔。它也分為隱式和顯式志衣,在RunLoop中修改“動(dòng)畫屬性”,如果當(dāng)前沒有創(chuàng)建CATransaction猛们,系統(tǒng)會(huì)自動(dòng)創(chuàng)建一個(gè)CATransaction念脯,并在當(dāng)前線程的下一個(gè)RunLoopcommit這個(gè)CATransaction,這種動(dòng)畫方式稱為隱式動(dòng)畫弯淘。使用CATransaction類中的[CATransaction begin][CATransaction commit]等相關(guān)方法創(chuàng)建的動(dòng)畫稱為顯式動(dòng)畫绿店。顯式事務(wù)中可以定義事務(wù)中所有動(dòng)畫的運(yùn)行時(shí)間和時(shí)間函數(shù),此外庐橙,還有這個(gè)方法+ (void)setDisableActions:(BOOL)flag能顯式的關(guān)閉這個(gè)事務(wù)中的action查詢操作假勿,關(guān)閉了查詢也就是關(guān)閉了動(dòng)畫效果,屬性值的變化就會(huì)立即生效态鳖,而沒有動(dòng)畫效果了转培。

關(guān)聯(lián)引申??????????
隱式動(dòng)畫的原理是:當(dāng)我們直接對(duì)可動(dòng)畫屬性賦值的時(shí)候,由于有隱式動(dòng)畫存在的可能浆竭,CALayer首先會(huì)判斷此時(shí)有沒有隱式動(dòng)畫被觸發(fā)浸须。它會(huì)讓它的delegate(沒錯(cuò)CALayer擁有一個(gè)屬性叫做delegate)調(diào)用actionForLayer:forKey:來獲取一個(gè)返回值惨寿,這個(gè)返回值在聲明的時(shí)候是一個(gè)id對(duì)象,當(dāng)然在運(yùn)行時(shí)它可能是任何對(duì)象删窒。這時(shí)CALayer拿到返回值缤沦,將進(jìn)行判斷:如果返回的對(duì)象是一個(gè)nil,則進(jìn)行默認(rèn)的隱式動(dòng)畫易稠;如果返回的對(duì)象是一個(gè)[NSNull null] 缸废,則CALayer不會(huì)做任何動(dòng)畫;如果是一個(gè)正確的實(shí)現(xiàn)了CAAction協(xié)議的對(duì)象驶社,則CALayer用這個(gè)對(duì)象來生成一個(gè)CAAnimation企量,并加到自己身上進(jìn)行動(dòng)畫。

以重寫的CALayer的position屬性的setter方法作例子:

- (void)setPosition:(CGPoint)position
{
    if ([self.delegate respondsToSelector:@selector(actionForLayer:forKey:)]) {
        id obj = [self.delegate actionForLayer:self forKey:@"position"];
        if (!obj) {
            // 隱式動(dòng)畫
        } else if ([obj isKindOfClass:[NSNull class]]) {
            // 直接重繪(無動(dòng)畫)
        } else {
            // 使用obj生成CAAnimation
            CAAnimation * animation;
            [self addAnimation:animation forKey:nil];
        }
    }
}

CATransaction屬性介紹:

//在當(dāng)前線程開啟一個(gè)新的事務(wù)
+ (void)begin;

//提交當(dāng)前事務(wù)期間所做的全部修改亡电,如果不存在事務(wù)則會(huì)引發(fā)異常
+ (void)commit;

//提交一個(gè)現(xiàn)存的隱士事務(wù)届巩,將推遲提交知道實(shí)際提交嵌套的顯示事務(wù)已經(jīng)完成
+ (void)flush;

//加鎖,保證線程安全
+ (void)lock;
+ (void)unlock;

//獲取和設(shè)定事務(wù)持續(xù)時(shí)間份乒,默認(rèn)為:0.25
+ (CFTimeInterval)animationDuration;
+ (void)setAnimationDuration:(CFTimeInterval)dur;

//暫時(shí)禁用圖層的行為
+ (BOOL)disableActions;
+ (void)setDisableActions:(BOOL)flag;

CATransaction動(dòng)畫的基本寫法及示例代碼:

[CATransaction begin];  
[CATransaction setDisableActions:YES];  //關(guān)閉動(dòng)畫  
[CATransaction setValue:@(0.5f) forKey:kCATransactionAnimationDuration];  //動(dòng)畫時(shí)間  
animationLayer.position = CGPointMake(100, 100);  
[CATransaction commit];

注意:事務(wù)還支持嵌套恕汇,當(dāng)嵌套的時(shí)候,只有最外層的事務(wù)commit了之后或辖,整個(gè)動(dòng)畫才會(huì)開始瘾英。

五、UIImageView的動(dòng)畫

UIImageView的動(dòng)畫是可以讓一系列的圖片在特定的時(shí)間內(nèi)按照順序顯示颂暇。
UIImageView類中有關(guān)動(dòng)畫的屬性和方法介紹:

//動(dòng)畫普通狀態(tài)下的圖片數(shù)組
@property (nullable, nonatomic, copy) NSArray<UIImage *> *animationImages;
//動(dòng)畫高亮狀態(tài)下的圖片數(shù)組
@property (nullable, nonatomic, copy) NSArray<UIImage *> *highlightedAnimationImages;
//動(dòng)畫持續(xù)時(shí)間
@property (nonatomic) NSTimeInterval animationDuration;       
//動(dòng)畫重復(fù)次數(shù)
@property (nonatomic) NSInteger      animationRepeatCount;

- (void)startAnimating;    //開始動(dòng)畫
- (void)stopAnimating;     //結(jié)束動(dòng)畫
- (BOOL)isAnimating;       //是否在動(dòng)畫中

UIImageView的使用方法很簡單按照要求傳值即可缺谴,示例代碼:

NSArray *imagesArray = @[[UIImage imageNamed:@"image1.png"],
                         [UIImage imageNamed:@"image2.png"],
                         [UIImage imageNamed:@"image3.png"]];
UIImageView *imageView = [UIImageView alloc] init];
[imageView setFrame:CGRectMake(0, 0, 100, 100)];
imageView.animationImages = imagesArray;  //將序列幀數(shù)組賦給animationImages屬性
imageView.animationDuration = 0.25;  //設(shè)置動(dòng)畫時(shí)間
imageView.animationRepeatCount = 0;  //設(shè)置動(dòng)畫次數(shù) 0 表示無限
[self.view addSubview:imageView];
[imageView startAnimating];  //開始播放動(dòng)畫

值得注意的地方是:圖片較少的情況,這種方法最簡單實(shí)用耳鸯;但如果圖片很多的話湿蛔,這種方式可能會(huì)導(dǎo)致程序出現(xiàn)問題。
UIImageView動(dòng)畫的其他缺陷是:動(dòng)畫不能夠?qū)崿F(xiàn)暫停只能停止县爬。如有暫停的需求時(shí)阳啥,用animationImages這種方式實(shí)現(xiàn)已經(jīng)不太滿足要求。我們可以使用NSTimer去實(shí)現(xiàn)UIImageViewanimation的效果财喳,用NSTimer每隔一個(gè)時(shí)間戳去設(shè)置一次image察迟,具體代碼如下:

//創(chuàng)建定時(shí)器定時(shí)更新圖片內(nèi)容
NSTimer *animatedTimer = [NSTimer scheduledTimerWithTimeInterval:0.04 
                                                          target:self 
                                                        selector:@selector(updateImageViewContentMethod) 
                                                        userInfo:nil 
                                                         repeats:YES];

//在定時(shí)器方法中更新圖片內(nèi)容                                                         
- (void)updateImageViewContentMethod
{
   animatedView.image = [UIImage imageNamed:[NSStringstringWithFormat:@"image%i.png",index]];
}

六、UIActivityIndicatorView的動(dòng)畫

UIActivityIndicatorView的是一個(gè)可以旋轉(zhuǎn)的進(jìn)度輪纲缓,一般用來當(dāng)loading使用卷拘。
UIActivityIndicatorView的類介紹:

//進(jìn)度輪的風(fēng)格
@property(nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle;
//當(dāng)動(dòng)畫停止時(shí)是否隱藏進(jìn)度輪
@property(nonatomic) BOOL                         hidesWhenStopped;
//iOS5后添加的設(shè)置進(jìn)度輪顏色的屬性
@property (nullable, readwrite, nonatomic, strong) UIColor *color;
//初始化方法
- (id)initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyle)style;
- (id)initWithFrame:(CGRect)frame;
//開始旋轉(zhuǎn)
- (void)startAnimating;
//結(jié)束旋轉(zhuǎn)
- (void)stopAnimating;
//是否正在旋轉(zhuǎn)
- (BOOL)isAnimating;

UIActivityIndicatorView的初始化方法一般使用initWithActivityIndicatorStyle方法,UIActivityIndicatorViewStyle有三個(gè)枚舉值可供選擇:

enum {
    UIActivityIndicatorViewStyleWhiteLarge  //大型白色指示器    
    UIActivityIndicatorViewStyleWhite       //標(biāo)準(zhǔn)尺寸白色指示器    
    UIActivityIndicatorViewStyleGray        //灰色指示器祝高,用于白色背景
};

基本使用方法及示例代碼:

UIActivityIndicatorView *animationView = nil;
animationView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
animationView.center = self.view.center;
[animationView setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
[animationView setBackgroundColor:[UIColor lightGrayColor]];
[self.view addSubview:animationView];
[animationView startAnimating];

關(guān)聯(lián)引申??????????
關(guān)于另一種旋轉(zhuǎn)輪:經(jīng)常在網(wǎng)絡(luò)請(qǐng)求時(shí)狀態(tài)欄上也出現(xiàn)旋轉(zhuǎn)輪栗弟,這個(gè)是怎么添加的。具體代碼:

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末工闺,一起剝皮案震驚了整個(gè)濱河市乍赫,隨后出現(xiàn)的幾起案子瓣蛀,更是在濱河造成了極大的恐慌,老刑警劉巖雷厂,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惋增,死亡現(xiàn)場離奇詭異,居然都是意外死亡改鲫,警方通過查閱死者的電腦和手機(jī)诈皿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來像棘,“玉大人稽亏,你說我怎么就攤上這事÷铺猓” “怎么了截歉?”我有些...
    開封第一講書人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長烟零。 經(jīng)常有香客問我瘪松,道長,這世上最難降的妖魔是什么锨阿? 我笑而不...
    開封第一講書人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任宵睦,我火速辦了婚禮,結(jié)果婚禮上群井,老公的妹妹穿的比我還像新娘状飞。我一直安慰自己毫胜,他們只是感情好书斜,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著酵使,像睡著了一般荐吉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上口渔,一...
    開封第一講書人閱讀 52,337評(píng)論 1 310
  • 那天样屠,我揣著相機(jī)與錄音,去河邊找鬼缺脉。 笑死痪欲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的攻礼。 我是一名探鬼主播业踢,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼礁扮!你這毒婦竟也來了知举?” 一聲冷哼從身側(cè)響起瞬沦,我...
    開封第一講書人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎雇锡,沒想到半個(gè)月后逛钻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锰提,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年曙痘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片立肘。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡屡江,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赛不,到底是詐尸還是另有隱情惩嘉,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布踢故,位于F島的核電站文黎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏殿较。R本人自食惡果不足惜耸峭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望淋纲。 院中可真熱鬧劳闹,春花似錦、人聲如沸洽瞬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伙窃。三九已至菩颖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間为障,已是汗流浹背晦闰。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鳍怨,地道東北人呻右。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像鞋喇,于是被迫代替她去往敵國和親声滥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359

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

  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果确徙,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜醒串,今天將帶大家一窺ios動(dòng)畫全貌执桌。在這里你可以看...
    每天刷兩次牙閱讀 8,514評(píng)論 6 30
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜芜赌,今天將帶大家一窺iOS動(dòng)畫全貌仰挣。在這里你可以看...
    F麥子閱讀 5,115評(píng)論 5 13
  • 前言 本文只要描述了iOS中的Core Animation(核心動(dòng)畫:隱式動(dòng)畫、顯示動(dòng)畫)缠沈、貝塞爾曲線膘壶、UIVie...
    GitHubPorter閱讀 3,636評(píng)論 7 11
  • 在iOS實(shí)際開發(fā)中常用的動(dòng)畫無非是以下四種:UIView動(dòng)畫,核心動(dòng)畫洲愤,幀動(dòng)畫颓芭,自定義轉(zhuǎn)場動(dòng)畫。 1.UIView...
    請(qǐng)叫我周小帥閱讀 3,112評(píng)論 1 23
  • 目錄: 主要繪圖框架介紹 CALayer 繪圖 貝塞爾曲線-UIBezierPath CALayer子類 補(bǔ)充:i...
    Ryan___閱讀 1,682評(píng)論 1 9