最近在做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)容及其使用版姑。
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
表制,而不是UIView
的RootLayer
的叫做非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)畫壤短,但是在UIVIew
的animation block
方法中又重新啟用了它們。(有關(guān)UIView
和CALayer
介紹稍后詳說)
需要注意的是:使用UIView
的動(dòng)畫方法慨仿,只能針對(duì)動(dòng)畫屬性修改才能產(chǎn)生動(dòng)畫效果久脯。UIView
支持的動(dòng)畫屬性有frame
、bounds
镰吆、center
帘撰、transform
、alpha
万皿、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)畫代碼寫在begin
和commit
之間就完成了動(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)容做粤。
UIView
的block動(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)畫使用也比較簡單巾遭,把之前寫在begin
和commit
之間的代碼移動(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
框架是基于OpenGL
與Core Graphics
圖像處理框架的一個(gè)跨平臺(tái)的動(dòng)畫框架夭禽。在真實(shí)的開發(fā)中,一般還是主要使用UIView封裝的動(dòng)畫谊路,而很少使用Core Animation
的動(dòng)畫讹躯;使用UIView
和CALayer
都能實(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)畫前酷麦,我們先了解下UIView
和CALayer
之間的聯(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
(位圖)更新顯示。
UIView
是iOS
系統(tǒng)中界面元素的基礎(chǔ)抖拦,所有的界面元素都是繼承自UIView
類还蹲,它真正的繪圖部分裸删,是由一個(gè)CALayer
類來管理。每個(gè)UIView
默認(rèn)就包含一個(gè)CALayer
屬性,UIView
就像是一個(gè)CALayer
的管理器账蓉,在View
顯示的時(shí)候,UIView
做為CALayer
的CALayerDelegate
傅瞻,UIView
的顯示內(nèi)容由內(nèi)部的CALayer
來顯示亲澡。訪問UIView
的與繪圖和跟坐標(biāo)有關(guān)的屬性,例如frame
凿菩、bounds
等,實(shí)際上內(nèi)部都是在訪問它所包含的CALayer
的相關(guān)屬性帜讲。有人說UIView
就像一個(gè)畫板蓄髓,而layer
就像畫布,一個(gè)畫板上可以有很多塊畫布舒帮,但是畫布不能有畫板会喝。
CALayer
和UIView
類似都擁有自己的樹形結(jié)構(gòu),UIView
包含很多subView
玩郊,而CALayer
是可以包含subLayer
的肢执,因此形成了圖層樹,CALayer
層是可以嵌套的译红,可以向它的layer
上添加subLayer
预茄,來完成某些特殊內(nèi)容的顯示。
UIView
與CALayer
的主要區(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í)是CALayer
的present Layer
的屬性值髓堪,而最終展示在界面上的其實(shí)是提供UIView
的modelLayer
。
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)畫是
iOS
和OS 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)系與常用屬性如下圖
CAAnimation
是所有動(dòng)畫對(duì)象的父類咳焚,它遵守CAMediaTiming
協(xié)議,負(fù)責(zé)控制動(dòng)畫的時(shí)間庞溜、速度和時(shí)間曲線等等革半,是一個(gè)抽象類,不能直接使用。CAPropertyAnimation
是CAAnimation
的子類又官,它支持動(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è)RunLoop
中commit
這個(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)UIImageView
的animation
的效果财喳,用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];