Gif图片是非常常见的图片格式,尤其是在聊天的过程中,Gif表情使用地很频繁。但是iOS竟然没有现成的支持加载和播放Gif的类。

简单的上网搜了一下,大概有三种方法:

1、使用UIWebView

    // 读取gif图片数据NSData *data = [NSData dataWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"001" ofType:@"gif"]];    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,200,200)];[webView loadData:data MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];[self.view addSubview:webView];

但是使用UIWebView的弊端在于,不能设置Gif动画的播放时间。

2、将Gif拆分成多张图片,使用UIImageView播放

最好把所需要的Gif图片打包到Bundle文件内,如下图所示

Loading.png
- (NSArray *)animationImages
{NSFileManager *fielM = [NSFileManager defaultManager];NSString *path = [[NSBundle mainBundle] pathForResource:@"Loading" ofType:@"bundle"];NSArray *arrays = [fielM contentsOfDirectoryAtPath:path error:nil];NSMutableArray *imagesArr = [NSMutableArray array];for (NSString *name in arrays) {UIImage *image = [UIImage imageNamed:[(@"Loading.bundle") stringByAppendingPathComponent:name]];if (image) {[imagesArr addObject:image];}}return imagesArr;
}- (void)viewDidLoad {[super viewDidLoad];UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:frame];gifImageView.animationImages = [self animationImages]; //获取Gif图片列表gifImageView.animationDuration = 5;     //执行一次完整动画所需的时长gifImageView.animationRepeatCount = 1;  //动画重复次数[gifImageView startAnimating];[self.view addSubview:gifImageView];
}

3、使用SDWebImage

但是很遗憾,SDWebImage这个方法是不能播放Gif的,它只能显示Gif的第一张图片而已。So,此方法被KO

    UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:frame];[gifImageView sd_setImageWithURL:nil placeholderImage:[UIImage imageNamed:@"gifTest.gif"]];

其实,在SDWebImage这个库里有一个UIImage+GIF的类别,里面为UIImage扩展了三个方法:

@interface UIImage (GIF)
+ (IImage *)sd_animatedGIFNamed:(NSString *)name;
+ (UIImage *)sd_animatedGIFWithData:(NSData *)data;
- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size;
@end

大家一看就知道,我们要获取处理后的Gif图片,其实只要调用前面两个中的其中一个方法就行了

注意:第一个只需要传Gif的名字,而不需要带扩展名(如Gif图片名字为001@2x.gif,只需传001即可)

我们就使用第二个方法试一试效果:

    NSString *path = [[NSBundle mainBundle] pathForResource:@"gifTest" ofType:@"gif"];NSData *data = [NSData dataWithContentsOfFile:path];UIImage *image = [UIImage sd_animatedGIFWithData:data];gifImageView.image = image;

然后通过断点,我们看下获取到的image是个什么样的东东:

img.png

我们发现:

image的isa指针指向了_UIAnimatedImage ,说明它是一个叫作_UIAnimatedImage 的类(当然,这个_UIAnimatedImage 苹果是不会直接让我们使用的)
_images 表示:这个Gif包含了多少张图片
_duration表示:执行一次完整动画所需的时长

其实,动画执续时间_duration也可以更改!
我们来看下此方法的内部实现:

+ (UIImage *)sd_animatedGIFWithData:(NSData *)data {if (!data) {return nil;}CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);size_t count = CGImageSourceGetCount(source);UIImage *animatedImage;if (count <= 1) {animatedImage = [[UIImage alloc] initWithData:data];}else {NSMutableArray *images = [NSMutableArray array];NSTimeInterval duration = 0.0f;for (size_t i = 0; i < count; i++) {CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);duration += [self sd_frameDurationAtIndex:i source:source];[images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];CGImageRelease(image);}if (!duration) {duration = (1.0f / 10.0f) * count;}animatedImage = [UIImage animatedImageWithImages:images duration:duration];}CFRelease(source);return animatedImage;
}

很明显,duration是可以随意更改的,只不过此方法设置了一个默认值
(duration = (1.0f / 10.0f) * count)

归根到底,创建新的动态的Image其实是调用了系统提供的一个UIImage的类方法而已:

 UIImage *animatedImage = [UIImage animatedImageWithImages:images duration:duration];

总结

1、使用UIWebView不可以设置duration,其他两种方法都可设置。而且方法1的容器为UIWebView ,其余两种的容器都是大家熟悉的UIImageView
2、方法2和方法3需要对应看应用场景

如:下拉、上拉加载控件需要一个根据拉动距离设置特定的Image,则需要使用方法2
直接显示Gif图片,则使用方法3会更方便

文/镜花水月_I(简书作者)
原文链接:http://www.jianshu.com/p/f0530a75c7af
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

iOS中GIF图片的加载相关推荐

  1. ListView中的图片异步加载、缓存

    一.ListView的图片异步加载 我们都知道对每一个Weibo Item都有用户头像,而且每一条微博还可能带有图片.如果在加载列表的同时加载图片,这样有几个缺点,第一很费事,界面卡住,用户体验很不好 ...

  2. React中实现图片懒加载

    1. 下载安装懒加载模块     cnpm i react-lazyload --save 2. 在src/assets/目录下放入懒加载占位图 placeholder.gif 3. 在需要使用懒加载 ...

  3. vue中实现图片懒加载的方法(一)

    1.背景: 前几天项目需求实现了图片瀑布流布局,就想着自己再实现图片的懒加载,瀑布流布局配合图片懒加载. 2.懒加载的意义 图片懒加载为的是提升网页性能,减少图片在同一时间请求很多网络图片资源,当然是 ...

  4. Android 数据库中读取图片名称加载相应的资源

    android的开发中会遇到这么一种需求,就是把图片存储到本地,每次加载的时候通过保存的图片的名称加载图片,或者利用请求到的/存储数据库存储的名称去加载图片 . 开始我把数据放在了assets中,开始 ...

  5. vue中的图片预加载

    1.首先添加一个loading加载页,给一张加载的图片 <div class="load" v-if="load"><img src=&quo ...

  6. 在qt中实现图片的加载

    (走了个弯路.用opencv显示qt图片...可以但没必要) 下面是常见的Qlabel加载图片 检测图片是否可以加载 QString filename = "C:\\Users\\Admin ...

  7. Vue中背景图片无法加载

    遇到过这种情况,调试的时候图片是存在的,能够在style中看到图片的,但是背景就是无法显示.特别奇怪的是如果不是给整个body加background或者对最外层的div的class加backgroun ...

  8. ubuntu篇----完美解决ubuntu中qq图片无法加载的问题

    显示图片 在本机的任意位置创建tim_ipv6.sh文件 我是在/opt下创建的 touch tim_ipv6.sh vim tim_ipv6.sh 在tim_ipv6.sh中写入 echo &quo ...

  9. 页面加载成功后调用_在微信小程序里实现图片预加载组件

    网页中的图片预加载 我们知道在 Web 页面中实现图片的预加载其实很简单,通常的做法是在 JS 中使用 Image 对象即可,代码大致如下 var image = new Image() image. ...

最新文章

  1. PIG 中COGROUP中的空值验证
  2. 【final】评价①
  3. Nginx的目录结构分析
  4. maven项目,httpclient jar包冲突
  5. c调用c++ qt_【C/C++】qt库结构及示例
  6. PhpMyAdmin 配置文件现在需要一个短语密码的解决方法
  7. ASP.NET- 执行SQL超时的解决方案
  8. 94. autoload(2)
  9. html5 风车特效
  10. 联想用u盘重装系统步骤_联想笔记本Y470 U盘重装系统过程教程
  11. java自己写一个消息队列_Java语言快速实现简单MQ消息队列服务
  12. 联想Y7000装双系统win10+Ubuntu16.04后在Ubuntu上Wifi被禁用的解决办法
  13. Excel密码保护怎么解密码
  14. 【转载】JPEG2000
  15. 编写MTK6737平台的GPIO驱动例程(三)
  16. 智源首席科学家孙茂松当选欧洲科学院外籍院士
  17. RFID固定资产条码标签管理系统,使资产更易盘点
  18. 免费的压缩/解压缩软件
  19. 信息学奥赛与大学计算机课程,信息学是什么课程
  20. 模拟信号超出频率范围

热门文章

  1. LeetCode 695. Max Area of Island
  2. 求100以内的素数(c语言)
  3. Linux驱动开发|4G通信
  4. 在 macOS 中使用密码保护压缩(zip)文件
  5. 国产CPU乱战遭遇生态壁垒:英特尔工艺领先龙芯两代
  6. 虚拟化-SDDC软件定义数据中心
  7. 13/6/21 Hella Intern Interview
  8. Iconfont-阿里巴巴矢量图标库 用 github账户无法登录
  9. 30岁转行学Python晚吗?在这个年龄我为什么会焦虑?
  10. 驻定相位原理在求解频域表达式中的应用