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 ...
随机推荐
- HTML-标签:图片 超链接
[img图片标签] 1,src属性:表示图片所在的路径. [路径的表示方式] ① 网络图片地址.并不建议使用. ② 可以使用图片的绝对路径.但是严禁使用绝对路径,因为绝对路径使用file://协议,网 ...
- ubuntu14.04 64位安装H3C iNode客户端
环境: OS:ubuntu14.04LTS 64位 iNode: iNode2.40-R0162 for linux(iNode只有32位的,而且是很久以前的版本) 安装方法: 第一种: 检查本机是6 ...
- JQuery中的回调对象
JQuery中的回调对象 回调对象(Callbacks object)模块是JQuery中的一个很基础的模块,很多其他的模块(比如Deferred.Ajax等)都依赖于Callbacks模块的实现.本 ...
- 关于excel的导入导出
目前为方便操作,很多系统都增加了批量导入导出的功能.文件导入导出一般的格式都是excel,现将常用设计用例总结如下: 批量导入 一.模板检查检测:一般excel导入,都会提供模板下载功能 1.模板 ...
- Entity Framework - 基于外键关联的单向一对一关系
代码的世界,原以为世界关系很简单,确道是关系无处不在.NET世界里ORM框架中EntityFramework作为其中翘楚,大大解放了搬砖工作的重复工作,着实提高了不少生产力,而也碰到过不少问题!比如关 ...
- java 面试,java 后端面试,数据库方面对初级和高级程序员的要求
本内容摘自 java web轻量级开发面试教程 对于合格的程序员,需要有基本的数据库操作技能,具体体现在以下三个方面. l 第一,针对一类数据库(比如MySQL.Oracle.SQL Server等 ...
- The C++ Programming Language 学习笔记 第四章 类型和声明
1.关于main 函数中的 return 0 C99标准中,main 函数的返回值类型必须是 int ,这样返回值才能传递给程序的激活者(如操作系统).如果 main 函数的最后没有写 return ...
- JVM内存结构和6大区域
摘自 http://www.iteye.com/news/30350 对于我们一般理解的计算机内存,它算是CPU与计算机打交道最频繁的区域,所有数据都是先经过硬盘至内存,然后由CPU再从内存中获取数据 ...
- [2012-06-21]结合find的awk
源起:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3754423&page=1&extra=#pid221729 ...
- 基于redis的延迟消息队列设计
需求背景 用户下订单成功之后隔20分钟给用户发送上门服务通知短信 订单完成一个小时之后通知用户对上门服务进行评价 业务执行失败之后隔10分钟重试一次 类似的场景比较多 简单的处理方式就是使用定时任务 ...