在app的引導(dǎo)頁中咕缎,經(jīng)常需要動態(tài)展示加載和交互過程,本文主要是對Gif動畫的調(diào)研颁虐,技術(shù)要求如下:
- 支持復(fù)雜的動態(tài)效果
- 易于維護(hù)
- 易于開發(fā)
- 兼容iOS7和小屏
- 高性能
Gif動畫
優(yōu)點(diǎn)
使用Gif動畫方式展示動態(tài)效果,具有很多優(yōu)點(diǎn),開發(fā)維護(hù)比較簡單虾标,工作量小,只需設(shè)計師提供動畫即可灌砖,相比原生制作動畫效率很高璧函。Gif還能夠?qū)崿F(xiàn)很復(fù)雜、酷炫的動畫特效基显,甚至有些是原生無法實(shí)現(xiàn)的蘸吓。Gif對系統(tǒng)版本,對屏幕尺寸沒有什么要求撩幽,兼容性較好库继。
缺點(diǎn)
當(dāng)然Gif也存在一些缺點(diǎn),它僅支持單頁動畫窜醉,對于連續(xù)性的多頁面動畫則無能為力宪萄,比如隨著引導(dǎo)頁滑動,一個按鈕將從第一頁飛到第二頁榨惰。它的cpu使用率也比較高拜英,每個Gif動畫增加了26%的cpu利用率(模擬器iphone 5,ios10.3)读串。
對于開源的引導(dǎo)頁類庫聊记,我們以EAIntroView為例撒妈,它的實(shí)現(xiàn)原理實(shí)際上是在一個scrollView容器上,平鋪四個imageView和一個指式條排监,劃動時切換到上/下一個頁面狰右。當(dāng)使用Gif動畫時,實(shí)際上將同時播放四個gif舆床,因此造成CPU使用率較高棋蚌,真機(jī)測試iOS10.3,iphone 6,cpu使用率70%左右挨队。
優(yōu)化
由于引導(dǎo)頁的實(shí)現(xiàn)方式是將多個imageView同時放到scrollView上谷暮,造成幾個Gif動畫同時播放,CPU使用率較高盛垦。為了解決這個問題湿弦,現(xiàn)引入FLAnimatedImage庫。這個庫支持停止腾夯、播放動畫颊埃。當(dāng)劃到某頁時,才會去播放當(dāng)前頁的Gif動畫蝶俱,這樣就降低了資源消耗情況班利,優(yōu)化后cpu利用率降低到32%。
Gif實(shí)例
寫了一個Demo榨呆,基于EAIntroView罗标,功能尚不完善,僅僅用于驗(yàn)證實(shí)際效果积蜻。地址:https://github.com/superzcj/ZCJGifInIntroDemo
self.gifArr = [NSMutableArray new];
NSMutableArray *views = [NSMutableArray new];
for (int i=0; i<4; i++) {
NSString *imageName = [NSString stringWithFormat:@"guideImage_%d", i + 1];
NSURL *url1 = [[NSBundle mainBundle] URLForResource:imageName withExtension:@"gif"];
NSData *data1 = [NSData dataWithContentsOfURL:url1];
FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:data1];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] initWithFrame:self.view.bounds];
imageView.backgroundColor = [UIColor clearColor];
imageView.animatedImage = image;
UIView *bgView = [[UIView alloc] initWithFrame:self.view.bounds];
[bgView addSubview:imageView];
[views addObject:bgView];
[self.gifArr addObject:imageView];
}
代碼如上闯割,首先從本地讀取Gif動畫圖片,生成FLAnimatedImage圖片對象竿拆,再傳遞給FLAnimatedImageView以顯示纽谒。為了在后面控制每個Gif對象的播放與停止,將Gif動畫容器放入gifArr數(shù)組中如输。
EAIntroPage *page1 = [EAIntroPage pageWithCustomView:views[0]];
EAIntroPage *page2 = [EAIntroPage pageWithCustomView:views[1]];
EAIntroPage *page3 = [EAIntroPage pageWithCustomView:views[2]];
EAIntroPage *page4 = [EAIntroPage pageWithCustomView:views[3]];
EAIntroView *intro = [[EAIntroView alloc] initWithFrame:self.view.bounds andPages:@[page1,page2,page3,page4]];
[intro.skipButton setTitle:@"跳過" forState:UIControlStateNormal];
[intro setDelegate:self];
intro.tapToNext = YES;
[intro showInView:self.view animateDuration:0.3];
創(chuàng)建四個引導(dǎo)頁頁面鼓黔,將上面生成的頁面內(nèi)容傳遞進(jìn)來,最后將引導(dǎo)頁添加到頁面上不见。
- (void)intro:(EAIntroView *)introView pageAppeared:(EAIntroPage *)page withIndex:(NSUInteger)pageIndex {
NSLog(@"Current page index = %lu", (unsigned long)pageIndex);
for (FLAnimatedImageView *iv in self.gifArr) {
[iv stopAnimating];
}
FLAnimatedImageView *imageView = self.gifArr[pageIndex];
[imageView startAnimating];
}
滑動引導(dǎo)頁時澳化,停止所有的Gif動畫,只播放新出現(xiàn)的當(dāng)前頁動畫稳吮。
FLAnimatedImage
FLAnimatedImage是由Flipboard開源的iOS平臺上播放GIF動畫的一個優(yōu)秀解決方案缎谷,在內(nèi)存占用和播放體驗(yàn)都有不錯的表現(xiàn)。它在Github上的Star有5461個灶似,被Facebook列林、Dropbox等應(yīng)用引用瑞你。
FLAnimatedImage的實(shí)現(xiàn)原理很簡單,只有兩個類希痴,F(xiàn)LAnimatedImage負(fù)責(zé)解析GIF動畫數(shù)據(jù)者甲,讀取Gif中的每一幀圖片,F(xiàn)LAnimatedImageView則展示FLAnimatedImage處理后的動畫數(shù)據(jù)砌创,控制Gif動畫的播放虏缸、停止等。
FLAnimatedImage利用CGImageSource獲取圖像對象嫩实、圖片屬性信息等刽辙,調(diào)用CGImageSourceCopyProperties方法獲取到Gif動畫循環(huán)次數(shù),調(diào)用CGImageSourceCreateImageAtIndex取得幀圖片甲献,然后根據(jù)GIF圖的大小和緩存策略判斷需要緩存的單幀圖片數(shù)量宰缤,緩存起來。
FLAnimatedImageView是UIImageView的子類晃洒,完全兼容UIImageView的各個方法撵溃。它設(shè)置GIF動畫的封面幀圖片,當(dāng)前幀索引锥累,GIF動畫的循環(huán)播放次數(shù),播放時間累加器集歇,更新是否發(fā)起動畫的標(biāo)志位桶略,判斷是否啟動GIF動畫。
第三方庫動態(tài)引導(dǎo)頁
使用第三方的動態(tài)引導(dǎo)頁類庫诲宇,能大大提升開發(fā)效率际歼。
JazzHands是一個動態(tài)引導(dǎo)頁類庫,它是基于關(guān)鍵幀的動畫框架, 可以用于手勢姑蓝,滾動視圖鹅心,KVO或者ReactiveCocoa, 十分方便。它在Github上star數(shù)有6102纺荧,在引導(dǎo)頁類庫中最受歡迎旭愧。
官方提供了一個很酷炫的Demo,地址:https://github.com/IFTTT/JazzHands宙暇。
總結(jié)
Gif動畫 | 第三方庫(JazzHands) | 動畫 | |
---|---|---|---|
開發(fā)工作量 | 低 | 高 | 極高 |
維護(hù)工作量 | 低 | 高 | 極高 |
cpu利用率和內(nèi)存占用 | 高(26%的cpu利用率) | 低(cpu使用率在10%) | 低 |
兼容性 | 支持iOS7输枯,支持小屏幕 | 支持ios7,支持小屏幕 | 支持 |
適用性 | 僅支持單頁動畫 | 支持多種類型動畫 | 無限制 |