iOS开发之加载、滑动翻阅大量图片优化解决方案
本文转载至 http://mobile.51cto.com/iphone-413267.htm
今天分享一下私人相册中,读取加载、滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制。我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清大图全屏浏览界面的这短暂的1秒内(和后续的几秒),都发生了什么。
今天分享一下私人相册中,读取加载、滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制。
我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清大图全屏浏览界面的这短暂的1秒内(和后续的几秒),都发生了什么。
常规思路流程
点击任意小图后,
1.首先制作scrollview框架:大小2个scrollview,小的用于手势缩放单一图片,大的横向依次加载全部照片
2.制作好scrollview框架后,加载照片
3.一切准备就绪跳转页面呈现给用户选择的大图
加载图片这一步,若相册内就10几张照片,那么毫无技术挑战,但是如果是300张照片呢?直接崩溃?还是让用户等待加载? 时间紧任务重,这一步需要拆分和优化.
scrollview框架需要了解下API,然后动动脑子了,这里有个小窍门,很多人都问我照片与照片间的黑边间距怎么实现,呵呵,贴下代码:
- #define PADDING 20
- - (NSInteger)loadPhotos
- {
- //清理之前照片
- for (UIView *v in [_scrollView subviews]) {
- [v removeFromSuperview];
- }
- workingFrame = [[UIScreen mainScreen]bounds];
- workingFrame.origin.x = PADDING;
- for (int i = 0; i < int_total; i++) {
- CGRect frame = workingFrame;
- WQPhoto *photoView = [[WQPhoto alloc] initWithFrame:frame];
- [photoView setScroller:self];
- [photoView setIndex:i];
- WQAlbumPhoto *photo = [albumObject._photos objectAtIndex:i];
- [photo cleanThumbnail];
- if (i == int_current) {
- //加载原图
- [photoView setImage:photo.oriImage];
- [photoView setIsLoad:YES];
- }else if (int_current - 10 < i && i < int_current + 10){
- //加载左右临近的缩略图
- [photoView setImage:photo.thumbnail4view];
- }
- [_scrollView addSubview:photoView];
- workingFrame.origin.x = workingFrame.origin.x + 2 * PADDING
- + workingFrame.size.width;
- }
- //实现可滚动
- [_scrollView setContentSize:CGSizeMake(workingFrame.origin.x, workingFrame.size.height / 2)];
- [_scrollView setContentOffset:CGPointMake(360 * int_current, 0)];
- //加载其余缩略图
- loadThread = [[NSThread alloc]initWithTarget:self selector:@selector(loadImages) object:nil];
- return 0;
- }
使用低分辨率图
仔细想想,其实没有必要第一时间加载全部图片的高清原图,事先存好每张图配套的低分辨率图,用空间换时间。
先加载所有的图片的低分辨率图, 当用户翻阅到某一张图片时, 即时的加载原始尺寸的高清无码大图. 过程优化为:
多线程任务
即使是这样,当照片数量达到一定量时,需要消耗的时间也并非毫秒级,体验无法领人满意, 页面跳转时仍然会出现卡顿现象。
于是考虑使用多线程来进一步拆分任务, 执行跳转的同时再后台执行加载低分辨率图的步骤.
优化快速翻阅体验
通过这样的拆分,可以实现立即跳转,体验满意。但是翻阅浏览时,当用户很快左右滑动时, 出现黑屏的几率很高, 因为加载低分辨率图任务的线程可能还在进行大量IO操作,不能及时跟上。 为了完善它,要把加载低分辨率图的步骤再次分解,精益求精。
在页面跳转时间允许的范围内,加载用户选定的那张图片的高清原图的同时,尽可能多的加载几张左右临近的图片的低分辨率图。
如何加载其余的低分辨率图?
以用户点击选定的那张图为中心向两边加载, 直接想应该是两个线程一左一右的加载,再想想左右一起加载其实可以是一个循环, 免了再开线程的那些耗费了。
- -(BOOL)loadImages
- {
- for (int i = int_current - 10, j = int_current + 10 ; !( i < 0 && int_total - 1 < j); --i, ++j) {
- if (!(i < 0)) {
- WQPhoto *photo_pre = [_scrollView.subviews objectAtIndex:i];
- WQAlbumPhoto *photoPre = [albumObject._photos objectAtIndex:i];
- [photo_pre setImage:photoPre.thumbnail4view];
- }
- if (!(int_total - 1 < j)) {
- WQPhoto *photo_next = [_scrollView.subviews objectAtIndex:j];
- WQAlbumPhoto *photoNext = [albumObject._photos objectAtIndex:j];
- [photo_next setImage:photoNext.thumbnail4view];
- }
- }
- return YES;
- }
最后还一个砍儿
尽量减少内存占用. 因为原始图片要比低分辨率图大很多, 所以当用户从一张图片翻阅到另一张图片时, 当前图片加载为原始尺寸的高清大图, 而原来那张就被替换为低分辨率图了。 虽然读写次数增多了, 但内存确实省了不少。
实话说,市场上不少相册类的app, 翻阅时都会有卡顿的跳跃感,呵呵……
iOS开发之加载、滑动翻阅大量图片优化解决方案的更多相关文章
- [IOS 开发] 懒加载 (延迟加载) 的基本方式,好处,代码示例
懒加载的好处: 1> 不必将创建对象的代码全部写在viewDidLoad方法中,代码的可读性更强 2> 每个属性的getter方法中分别负责各自的实例化处理,代码彼此之间的独立性强,松耦合 ...
- iOS开发图片加载的内存问题及优化方案
原创作者:Magic-Unique 原文地址:https://github.com/Magic-Unique/HXImage猿吧 - 资源共享论坛: http://www.coderbar.cn 做最 ...
- ios开发中加载的image无法显示
昨天遇到一个较奇葩的问题,imageName加载的图片显示不出来,网上查了好多资料还是没找到解决的方法: 之前图片是放在项目中SupportingFiles文件下的,怎么加载都能显示图片,于是将图片拿 ...
- iOS - 开发中加载本地word/pdf文档说明
最近项目中要加载一个本地的word/pdf等文件比如<用户隐私政策><用户注册说明>,有两种方法加载 > 用QLPreviewController控制器实现 步骤 : & ...
- iOS 开发笔记-加载/初始化
ViewDidLoad 一般我们会在这里做界面上的初始化操作,比如往view中添加一些子视图.从数据库或者网络加载模型数据装配到子视图中 在自定义控制里 initWithFrame:一般用于添加控件, ...
- iOS开发-UIWebView加载本地和网络数据
UIWebView是内置的浏览器控件,可以用它来浏览网页.打开文档,关于浏览网页榜样可以参考UC,手机必备浏览器,至于文档浏览的手机很多图书阅读软件,UIWebView是一个混合体,具体的功能控件内置 ...
- Android开发--异步加载
因为移动端软件开发思维模式或者说是开发的架构其实是不分平台和编程语言的,就拿安卓和IOS来说,他们都是移动前端app开发展示数据和用户交互数据的数据终端,移动架构的几个大模块:UI界面展示.本地数据可 ...
- iOS开发——加载、滑动翻阅大量图片解决方案详解
加载.滑动翻阅大量图片解决方案详解 今天分享一下私人相册中,读取加载.滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制. 我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清 ...
- iOS开发UI篇—从代码的逐步优化看MVC
iOS开发UI篇—从代码的逐步优化看MVC 一.要求 要求完成下面一个小的应用程序. 二.一步步对代码进行优化 注意:在开发过程中,优化的过程是一步一步进行的.(如果一个人要吃五个包子才能吃饱,那么他 ...
随机推荐
- es6总结(七)--数据结构-Set & Map
- How to build and run ARM Linux on QEMU from scratch
This blog shows how to run ARM Linux on QEMU! This can be used as a base for later projects using th ...
- 第6章 I/O多路复用
前一章节客户端同时处理两个输入:标准输入和TCP套接字,然而问题在于客户端阻塞于fgets调用期,服务器进程被杀死后,服务器tcp虽然可以正确发送一个fin,但进程正阻塞于标准输入,它无法看到eof, ...
- php自动获取字符串编码函数mb_detect_encoding
当在php中使用mb_detect_encoding函数进行编码识别时,很多人都碰到过识别编码有误的问题,例如对与GB2312和UTF- 8,或者UTF-8和GBK(这里主要是对于cp936的判断), ...
- Reactjs 的 PropTypes 使用方法
propTypes 使用來規範元件Props的型別與必需狀態 var Test = React.createClass({ propTypes: { // required requiredFunc: ...
- Java原来如此-几种常见的排序--冒泡排序(Bubble Sort)
冒泡排序的原理:假设要求的数组是正序,两两进行比较,如果前一个数比后一个数小,位置不变.如果前一个数比后一个数大,位置互换,再跟后一个数进行比较,直到最后.就是逐步把大数送到最后. 举个例子:int[ ...
- 在路上:安全公司“跨界”SD-WAN
编者按:本文是SDNLAB“企业+”特别报道之一.“企业+”是SDNLAB重点打造的栏目,汇聚信息行业运营商.设备商.互联网公司.软件公司.集成公司.融创投资公司.科研院所等企业,重新定义IT行业撮合 ...
- Database | SQL
Basic of MySQL 创建数据库: mysql> create database xxj; Query OK, row affected (0.00 sec) 列举数据库: mysql& ...
- UvaLive 4287 Proving Equivalences 强连通缩点
原题链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- Parameter Binding in ASP.NET Web API #Reprinted
http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api