iOS启动图-从网络获取的gif图,在本地一直是没有动画,还模糊的
背景介绍:
APP启动页,常有静态图加链接,gif加链接,短视频等几种形式。
我们APP前期只有静态图这一种,功能已经实现。
之后,有了添加gif的需求,按理说,只要添加一个类型判断,按照数据类型,通过不同方法展示内容即可,但是一直不可以。。
出了这样的问题,下好的gif图,内容类型没错但是通过对应的gif方法显示的内容一直是一张静态图,并且还是模糊的。
因为之前的下载图片,以及显示图片的逻辑完全没问题,所以定位问题在显示gif的方法上,所以走了弯路,但是这条弯路是必然要走的。
下面开始我们的星辰大海,我们的目标是终结问题
先看源码--原来的代码
/**
* 下载新的图片
*/
+ (void)downloadAdImageWithUrl:(NSString *)imageUrl imageName:(NSString *)imageName imgLinkUrl:(NSString *)imgLinkUrl imgDeadline:(NSString *)imgDeadline imgStartline:(NSString *)imgstartline
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
UIImage *image = [UIImage imageWithData:data]; NSString *filePath = [self getFilePathWithImageName:imageName]; // 保存文件的名称
[UIImageJPEGRepresentation(image, 0) writeToFile:filePath atomically:YES];
if ([UIImageJPEGRepresentation(image, 0) writeToFile:filePath atomically:YES]) { // 保存成功
//判断保存下来的图片名字和本地沙盒中存在的图片是否一致,如果不一致,说明图片有更新,此时先删除沙盒中的旧图片,如果一致说明是删除缓存后再次下载,这时不需要进行删除操作,否则找不到已保存的图片
if (![imageName isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:adImageName] ]) {
[self deleteOldImage];
} [[NSUserDefaults standardUserDefaults] setValue:imageName forKey:adImageName];
[[NSUserDefaults standardUserDefaults] setValue:imageUrl forKey:adUrl];
[[NSUserDefaults standardUserDefaults] setValue:imgDeadline forKey:adDeadline];
[[NSUserDefaults standardUserDefaults] setValue:imgstartline forKey:adstartline];
//保存图片
// [[NSUserDefaults standardUserDefaults] setValue:@"" forKey:@"Deadline"];
// [[NSUserDefaults standardUserDefaults] setValue:@"" forKey:@"startline"];
[[NSUserDefaults standardUserDefaults] synchronize];//立即写入 }else{
NSLog(@"保存失败");
} });
}
/**
* 通过在沙盒路径,获取gif图
*/
-(void)setImgFilePath:(NSString *)imgFilePath{
_imgFilePath = imgFilePath;
if ([_imgFilePath hasSuffix:@"gif"]) {
_adImageView.image = [UIImage sd_animatedGIFWithData:[NSData dataWithContentsOfFile:imgFilePath]];
}else{
_adImageView.image = [UIImage imageWithContentsOfFile:_imgFilePath];
}
}
以上两个方法一个实现下载,一个实现显示,起初只有一张图片做启动图的时候,这种写法勉强用,虽然走了弯路,但是不会影响实现效果
但是新需求是需要加载gif,或许以后还有小视频
问题出来了
gif一直下载不下来,起初修改了方法,毕竟gif有3M不小,所以换了下载方法,如下
/**
* 这个方法,下图片还行,你要是下载个大点的gif那就不合适了
*/
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
UIImage *image = [UIImage imageWithData:data];
那就改成下边的下载方法,适合稍大一点的文件下载
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:imageUrl]]
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!connectionError) { } else { }
}];
但是下载解决了问题后,发现还不能正常显示,但是项目中其他地方是没问题的啊,所以一直纠结于下面这个赋图的方法,其实是完全没问题的,只是能数据就不对了
_adImageView.image = [UIImage sd_animatedGIFWithData:[NSData dataWithContentsOfFile:imgFilePath]];
读取数据没问题,只能是存数据的时候不对了
这个时候注意到,问题所在
原因是下载的图片资源没有直接保存到某个路径下,而是先转成图片,然后图片转data保存了,多此一举了,重要的是,gif图的话,就把原来的资源都改变了,用的时候,获取的资源自然就出问题了,我们看代码
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
UIImage *image = [UIImage imageWithData:data]; NSString *filePath = [self getFilePathWithImageName:imageName]; // 保存文件的名称
[UIImageJPEGRepresentation(image, 0) writeToFile:filePath atomically:YES];
if ([UIImageJPEGRepresentation(image, 0) writeToFile:filePath atomically:YES]){}
这是下载图片方法中的存储功能代码:获取data,转image,image写成data保存。我们可以看到多了一步,可能图片的时候,虽然多转换一步,图片资源没有改变,但是gif图用[UIImageJPEGRepresentation(image, 0) writeToFile:filePath atomically:YES];这个方法数据资源就改变了。所以导致图片虽然没问题,但是gif就不行了!
这儿其实不管他是何种类型资源直接保存data就好了。
下面是修改后的代码
+ (void)downloadAdImageWithUrl:(NSString *)imageUrl imageName:(NSString *)imageName imgLinkUrl:(NSString *)imgLinkUrl imgDeadline:(NSString *)imgDeadline imgStartline:(NSString *)imgstartline
{ [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:imageUrl]]
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!connectionError) { NSString *filePath = [self getFilePathWithImageName:imageName]; // 保存文件的名称 //图片data直接存储,不需要转image然后再转data
if ([data writeToFile:filePath atomically:YES]) { // 保存成功
//判断保存下来的图片名字和本地沙盒中存在的图片是否一致,如果不一致,说明图片有更新,此时先删除沙盒中的旧图片,如果一致说明是删除缓存后再次下载,这时不需要进行删除操作,否则找不到已保存的图片
if (![imageName isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:adImageName] ]) {
[self deleteOldImage];
} [[NSUserDefaults standardUserDefaults] setValue:imageName forKey:adImageName];
[[NSUserDefaults standardUserDefaults] setValue:imageUrl forKey:adUrl];
[[NSUserDefaults standardUserDefaults] setValue:imgDeadline forKey:adDeadline];
[[NSUserDefaults standardUserDefaults] setValue:imgstartline forKey:adstartline];
//保存图片
// [[NSUserDefaults standardUserDefaults] setValue:@"" forKey:@"Deadline"];
// [[NSUserDefaults standardUserDefaults] setValue:@"" forKey:@"startline"];
[[NSUserDefaults standardUserDefaults] synchronize];//立即写入 }else{
NSLog(@"保存失败");
} } else { }
}];
return;
}
测试之后,正常显示gif。。。问题得以解决!
总结,问题往往就在你以为不可能出错的地方!
作者流浪
iOS启动图-从网络获取的gif图,在本地一直是没有动画,还模糊的的更多相关文章
- Android LazyList 从网络获取图片并缓存
原演示地址 本文内容 环境 演示 LazyList 从网络获取图片并缓存 参考资料 本文是 Github 上的一个演示,通过网络获取歌手专辑的缩略图,并显示在 ListView 控件中.该演示具备将缩 ...
- 用rose画UML图(用例图,活动图)
用rose画UML图(用例图,活动图) 首先,安装rose2003,电脑从win8升到win10以后,发现win10并不支持rose2003的安装,换了rose2007以后,发现也不可以. 解决途径: ...
- iOS启动图和开屏广告图,类似网易
iOS启动图和开屏广告图,类似网易 启动图是在iOS开发过程中必不可少的一个部分,很多app在启动图之后会有一张自定义的开屏广告图,点击该广告图可以跳转到广告图对应的页面.今天呢,和大家分享一下如何添 ...
- iOS最笨的办法实现无限轮播图(网络加载)
iOS最笨的办法实现无限轮播图(网络加载) 简单的做了一下: 使用方法: 把 请求返回的 图片地址(字符串类型)放进数组中就行 可以使用SDWebImage(我就是用的这个)等..需要自己导入并引用, ...
- Android代码优化----PullToRefresh+universal-image-loader实现从网络获取数据并刷新
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- 关于iOS开发首次进入需要获取地理位置
今天给大家简单介绍一下iOS开发过程中会遇到的获取地理位置的问题,(话不多说进入正题)这里给大家讲解一下两种在APPdelegate获取地理位置的方法: 一:首先是用系统的方法获取地理位置: 1. 首 ...
- Android & iOS 启动画面工具
感谢Aone!为我们开发了如此便捷的工具!! 以下为原文: Android & iOS 启动画面工具 下载:OneSplash.启动画面工具.Aone.20190318.zip 说明:这一个 ...
- Android ListView 和 ***Adapter 从本地/网络获取歌曲列表
本文内容 环境 项目结构 测试数据 演示 1:SimpleAdapter 演示 2:BaseAdapter 演示 3:CustomLazyList 演示 4:CustomLazyCompleteLis ...
- Android Volley 库通过网络获取 JSON 数据
本文内容 什么是 Volley 库 Volley 能做什么 Volley 架构 环境 演示 Volley 库通过网络获取 JSON 数据 参考资料 Android 关于网络操作一般都会介绍 HttpC ...
随机推荐
- MBProgressHUD1.0.0源码解析
MBProgressHUD是一个显示提示窗口的三方库,常用于用户交互.后台耗时操作等的提示.通过显示一个提示框,通知用户操作或任务的执行状态:同时,利用动画效果,降低用户等待的焦虑心理,增强用户体验. ...
- css3文本字体
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JMeter安装和简介
1.Apache jmeter 是一个100%的纯java桌面应用,用于压力测试和性能测量.它最初被设计用于Web应用测试但后来扩展到其他测试领域,可以用于对静态的和动态的资源(文件,Servlet, ...
- 关于HttpSession
HttpSession 使用Cookie有一个非常大的局限,就是如果Cookie很多,则无形的增加了客户端与服务端的数据传输量.而且由于浏览器对Cookie数量的限制,注定我们不能再Cookie中保 ...
- 【秒懂】号称最为简明实用的Django上手教程
号称最为简明实用的Django上手教程 作者:白宁超 2017年8月24日09:37:35 摘要:Django的学习教程也是分门别类,形式不一.或是较为体系的官方文档,或者风格自由的博客文档,或者偏向 ...
- Python下的OpenCV学习 01 —— 在Linux下安装OpenCV
一.OpenCV简要介绍 OpenCV是一个跨平台的计算机视觉库,可以运行在Windows.Linux.MacOS等操作系统上.OpenCV提供了众多语言的接口,其中就包含了Python,Python ...
- 【Oracle】表空间管理
--表空间管理为主.附带 权限管理.数据字典 /* 表空间是逻辑结构,数据文件是物理结构 一个表空间对应多个段segment 段可以对应多个数据文件.跨磁盘 一个段对应多个盘区 extent 一个盘区 ...
- 在微信小程序的JS脚本中使用Promise来优化函数处理
在我们传统的Javascript开发函数编写中,我们习惯了回调函数的处理,不过随着回调函数的增多,以及异步处理的复杂性等原因,代码越来越难读,因此诞生了使用Promise来优化JS函数处理的需求,引入 ...
- hdu3081 Marriage Match II(二分+并查集+最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3081 题意: n个女生与n个男生配对,每个女生只能配对某些男生,有些女生相互是朋友,每个女生也可以跟她 ...
- Openfire分析之三:ConnectionManager 连接管理(1)
Openfire是怎么实现连接请求的? XMPPServer.start()方法,完成Openfire的启动.但是,XMPPServer.start()方法中,并没有提及如何监听端口,那么Openfi ...