一、引言
在iOS開發(fā)中,UIImageView類專門來負責圖片數(shù)據(jù)的渲染,并且UIImageView也有幀動畫的方法來播放一組圖片鹰晨,但是對于gif類型的數(shù)據(jù),UIImageView中并沒有現(xiàn)成的接口提供給開發(fā)者使用方淤,在iOS中一般可以通過兩種方式來播放gif動態(tài)圖,一種方式是通過ImageIO框架中的方法將gif文件中的數(shù)據(jù)進行解析,再使用coreAnimation核心動畫來播放gif動畫嘱丢,另一種方式計較簡單,可以直接通過webView來渲染gif圖祠饺。
二越驻、為原生的UIImageView添加類別來支持gif動態(tài)圖的播放
gif動態(tài)圖文件中包含了一組圖片及其信息,信息主要記錄著每一幀圖片播放的時間道偷,我們?nèi)绻@取到了gif文件中所有的圖片同時又獲取到每一幀圖片播放的時間缀旁,就可以為UIImageView添加核心動畫的方法來讓其播放gif的內(nèi)容了。
-(void)getGifImageWithUrk:(NSURL*)url returnData:(void(^)(
NSArray?*?imageArray,
NSArray*timeArray,
CGFloat totalTime,
NSArray*?widths,
NSArray*?heights))dataBlock{
//通過文件的url來將gif文件讀取為圖片數(shù)據(jù)引用
CGImageSourceRef source =CGImageSourceCreateWithURL((CFURLRef)url,NULL);
//獲取gif文件中圖片的個數(shù)
size_t count =CGImageSourceGetCount(source);
//定義一個變量記錄gif播放一輪的時間
float allTime=0;
//存放所有圖片
NSMutableArray* imageArray = [[NSMutableArrayalloc]init];
//存放每一幀播放的時間
NSMutableArray* timeArray = [[NSMutableArrayalloc]init];
//存放每張圖片的寬度 (一般在一個gif文件中勺鸦,所有圖片尺寸都會一樣)
NSMutableArray* widthArray = [[NSMutableArrayalloc]init];
//存放每張圖片的高度
NSMutableArray* heightArray = [[NSMutableArrayalloc]init];
//遍歷
for(size_t i=0; i<count;i++){
CGImageRef image = CGImageSourceCreatImageAtIndex(sources,NULL);
[imageArray addObject:(_bridge UIImage*)(image)];
CGImageRelease(image)
//獲取圖片信息
NSDictionary *info =(_bridge NSDictionary*)CGImageSourceCopyPropertiesAtIndex(sources,i,NULL);
CGFloat width = [[info objectForkey:(_bridge NSString*)kCGImagePropertyPixelWidth] floatValue];
CGFloat height = [[info objectForkey:(_bridge NSString*)kCGImagePropertyPixelHeight] floatValue];
[widthArray addObject:[NSNumber numberWithFloat:width]];
[heightArray addObject:[NSNumber numberWithFloat:height]];
NSDictionary *timeDic = [info objectForKey:(_bridge NNString *)kCGImagePropertyGIFDictionary];
CGFloat time = [[timeDic objectForKey:(_bridge NNString*)kCGImagePropertyGIFDelatime] floatValue];
allTime +=time;
[timeArray addObject:[NSnumber numberWithFloat:time]];
CFRelease(info)
}
CFRelease(source);
dataBlock(imageArray,timeArray,allTime,widthArray,heightArray)
}
為UIImageView 添加一個設(shè)置gif圖內(nèi)容的方法
-(void)setImage:(NSURL*)imageUrl{
__weak id __self = self;
[self getGifImageWithUrk:imageUrl returnData:^(NSArray *imageArray,NSArray *timeArray,CGFloattotalTime,NSArray *widths,NSArray *heights) {
//添加幀動畫
CAkeyframeAnimation *animation = [CAkeyframeAnimation animationwithkeyPath:@"contents"];
NSMutableArray *times = [[NSMutableArray alloc] init];
float currentTime = 0;
for (int i = 0; i<imageArray.count;i++){
[times addObject:[NSNumber numberWithFloat:currentTime/totalTime]];
currentTime +=[timeArray[i] floatValue];
}
[animation setKeyTimes:times];
[animation setValues:imageArray];
[animation setTimingFunchtion:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
//設(shè)置循環(huán)
animation.repeatCount = MaxFLOAT;
//設(shè)置播放總時長
animation.duration = totalTime;
[[(UIImageView*)_self layer] ?addAnimation:animation forKey:@"gifAnimation"];
}]
}
三并巍、使用UIwebView來加載gif動態(tài)圖數(shù)據(jù)
NSData *gifData = [ NSData dataWithContentsOfURL:imageUrl];
WKWebView *wkbview = [WkWebView alloc]initWithFrame:CGRectMake(0,0,self.frame.size.width,self.frame.size.height);
wkbview.backgroundColor =[UIColor clearColor];
wkbview.scalesPageToFit = YES;
[wkbview loadData:gitData MIMEType:@"image/gif" textEncodingName:nil baseURL:nil]
經(jīng)過測試,從加載速度上來說换途,通過UIImageView類別加載的方式更加快速懊渡,UIWebView的方式加載時間會稍長,但是從性能上來比較军拟,WebView的方式性能更優(yōu)剃执,播放的gif動態(tài)圖更加流暢。在開發(fā)中懈息,可以根據(jù)需求肾档,適當選擇,例如雖然WebView加載的方式性能更好辫继,但是在許多情況下怒见,原生的UIImageView能夠更加自由的讓開發(fā)者進行擴展
參考牛人,琿少的文章:https://my.oschina.net/u/2340880/blog/608560姑宽;