最近看了一下Gif播放,因為iOS是沒有可以直接播放Gif資源的控件的,所以,這就需要我們想辦法了。。。
準備
通過上網Google,也查到了一些相關方法,下面列舉一下:
-
UIWebView
播放
NSString *path = [[NSBundle mainBundle] pathForResource:@"niconiconi" ofType:@"gif"];
NSData *gifData = [NSData dataWithContentsOfFile:path];
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
webView.scalesPageToFit = YES;
[webView loadData:gifData MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];
webView.backgroundColor = [UIColor clearColor];
webView.opaque = NO;
[self.view addSubview:webView];
- 將GIF分解成多張PNG圖片,使用
UIImageView
播放
// 需導入 #import <ImageIO/ImageIO.h>
NSURL *fileUrl = [[NSBundle mainBundle] URLForResource:@"niconiconi" withExtension:@"gif"];
// 將GIF圖片轉換成對應的圖片源
CGImageSourceRef gifSource = CGImageSourceCreateWithURL((CFURLRef) fileUrl, NULL);
// 獲取圖片源個數,即由多少幀圖片組成
size_t frameCout = CGImageSourceGetCount(gifSource);
NSMutableArray *frames = [[NSMutableArray alloc] init];
for (size_t i = 0; i < frameCout; i++) {
// 從GIF圖片中取出源圖片
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(gifSource, i, NULL);
UIImage *imageName = [UIImage imageWithCGImage:imageRef];
[frames addObject:imageName];
CGImageRelease(imageRef);
}
UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
gifImageView.animationImages = frames;
gifImageView.animationDuration = 0.1;
[gifImageView startAnimating];
[self.view addSubview:gifImageView];
- 使用
SDWebImage
播放NSData數據的GIF+ (UIImage *)sd_animatedGIFWithData:(NSData *)data
NSString *filePath = [[NSBundle bundleWithPath:[[NSBundle mainBundle] bundlePath]] pathForResource:@"niconiconi" ofType:@"gif"];
NSData *imageData = [NSData dataWithContentsOfFile:filePath];
UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
gifImageView.backgroundColor = [UIColor clearColor];
gifImageView.image = [UIImage sd_animatedGIFWithData:imageData];
[self.view addSubview:gifImageView];
- 第三方播放Gif
FLAnimatedImage
YYImage
使用較多的第三方庫
FLAnimatedImage
使用
NSURL *url = [[NSBundle mainBundle] URLForResource:@"niconiconi" withExtension:@"gif"];
NSData *data = [NSData dataWithContentsOfURL:url];
FLAnimatedImage *animatedImage = [[FLAnimatedImage alloc] initWithAnimatedGIFData:data];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = image;
imageView.frame = CGRectMake(0.0, 0.0, 100.0, 100.0);
[self.view addSubview:imageView];
YYImage
使用
// YYImage可以加載包括gif,WebP,APNG等圖片
YYImage * image = [YYImage imageNamed:@"niconiconi"];
YYAnimatedImageView *imageView = [[YYAnimatedImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(0, 0, 300, 300);
[self.view addSubview:imageView];
- 對比總結
UIWebView
實現播放Gif簡單直接,如果只想單純的播放一下建議使用此方法。弊端就是只能循環播放,無法控制它的暫停和其他操作, 不夠靈活。
UIImageView
采用幀動畫將圖片一張張顯示,可以調節播放次數和速度但圖片過多過大內存會很有壓力。另外在保證播放的動畫清晰和時長的情況下Gif文件大小會遠小于多張PNG圖片的大小。
使用第三方播放Gif動畫可以對動畫進行一系列操作,暫停或者快進等操作,適合Gif文件比較大的情況下使用。
簡單應用
這里呢,我使用 FLAnimatedImage
第三方庫, 簡單實現了一個新特性引導動畫, 直接進行Gif播放,使用起來還算不錯 , 性能消耗也不是很大, 如下:
性能使用圖
實現原理也是很簡單,UIScrollView
+ FLAnimatedImageView
根據 contentOffset
控制當前頁數。
下面是幾個核心代碼:
// 設置初始顯示樣式
- (void)setupDefault {
self.scrollView.contentSize = CGSizeMake(SCREEN_WIDTH * TOTALCOUNT, 0);
for (int i = 0; i<TOTALCOUNT; i++) {
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
FLAnimatedImage *image = [self animatedImageWithURLForResource:[NSString stringWithFormat:@"引導頁%d",i+1]];
if (i == 0) {
imageView.animatedImage = image;
} else {
// 設置首幀圖片
imageView.image = image.posterImage;
}
imageView.frame = CGRectMake(SCREEN_WIDTH * i, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
[_scrollView addSubview:imageView];
[self.animatedImageViews addObject:imageView];
}
self.pageControl.numberOfPages = TOTALCOUNT;
}
// 根據Gif資源獲取FLAnimatedImage
- (FLAnimatedImage *)animatedImageWithURLForResource:(NSString *)fileName {
NSURL *url = [[NSBundle mainBundle] URLForResource:fileName withExtension:@"gif"];
NSData *data = [NSData dataWithContentsOfURL:url];
FLAnimatedImage *animatedImage = [[FLAnimatedImage alloc] initWithAnimatedGIFData:data];
return animatedImage;
}
// 滑到當前顯示頁數
- (void)setupAnimateImage:(int)page {
FLAnimatedImageView *imageView = self.animatedImageViews[page];
FLAnimatedImage *image = [self animatedImageWithURLForResource:[NSString stringWithFormat:@"引導頁%d",page+1]];
imageView.animatedImage = image;
if (page == TOTALCOUNT - 1) {
imageView.loopCompletionBlock= ^(NSUInteger loopCountRemaining) {
[UIView animateWithDuration:0.3 animations:^{
self.entryBtn.hidden = NO;
self.entryBtnBottom.constant = 75;
[self.entryBtn layoutIfNeeded];
}];
};
} else {
self.entryBtn.hidden = YES;
self.entryBtnBottom.constant = 0;
[self.entryBtn layoutIfNeeded];
}
}
// 每次滑到當前頁確保從首幀播放
- (void)setupFistFrameImageWithPage:(int)page {
// 設置首幀圖片,每次播放從首幀開始(如果不設置,滑回上一個會顯示最后一幀的圖片)
if (self.lastPage != page) {
if (self.lastPage < page ) {
FLAnimatedImageView *imageView1 = self.animatedImageViews[page-1];
imageView1.animatedImage = [self animatedImageWithURLForResource:[NSString stringWithFormat:@"引導頁%d",page]];
imageView1.image = imageView1.animatedImage.posterImage;
} else {
FLAnimatedImageView *imageView2 = self.animatedImageViews[page+1];
imageView2.animatedImage = [self animatedImageWithURLForResource:[NSString stringWithFormat:@"引導頁%d",page+2]];
imageView2.image = imageView2.animatedImage.posterImage;
}
}
}
使用效果預覽 :
guide.gif