最近看了一下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;
}
}
}
使用效果预览 :