iOS开发——加载、滑动翻阅大量图片解决方案详解

加载、滑动翻阅大量图片解决方案详解

今天分享一下私人相册中,读取加载、滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制。

我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清大图全屏浏览界面的这短暂的1秒内(和后续的几秒),都发生了什么。

常规思路流程

点击任意小图后,

1.首先制作scrollview框架:大小2个scrollview,小的用于手势缩放单一图片,大的横向依次加载全部照片

2.制作好scrollview框架后,加载照片

3.一切准备就绪跳转页面呈现给用户选择的大图

加载图片这一步,若相册内就10几张照片,那么毫无技术挑战,但是如果是300张照片呢?直接崩溃?还是让用户等待加载? 时间紧任务重,这一步需要拆分和优化.

scrollview框架需要了解下API,然后动动脑子了,这里有个小窍门,很多人都问我照片与照片间的黑边间距怎么实现,呵呵,贴下代码:

  1. #define PADDING  20
  2. - (NSInteger)loadPhotos
  3. {
  4. //清理之前照片
  5. for (UIView *v in [_scrollView subviews]) {
  6. [v removeFromSuperview];
  7. }
  8. workingFrame = [[UIScreen mainScreen]bounds];
  9. workingFrame.origin.x = PADDING;
  10. for (int i = 0; i < int_total; i++) {
  11. CGRect frame = workingFrame;
  12. WQPhoto *photoView = [[WQPhoto alloc] initWithFrame:frame];
  13. [photoView setScroller:self];
  14. [photoView setIndex:i];
  15. WQAlbumPhoto *photo = [albumObject._photos objectAtIndex:i];
  16. [photo cleanThumbnail];
  17. if (i == int_current) {
  18. //加载原图
  19. [photoView setImage:photo.oriImage];
  20. [photoView setIsLoad:YES];
  21. }else if (int_current - 10 < i && i < int_current + 10){
  22. //加载左右临近的缩略图
  23. [photoView setImage:photo.thumbnail4view];
  24. }
  25. [_scrollView addSubview:photoView];
  26. workingFrame.origin.x = workingFrame.origin.x + 2 * PADDING
  27. + workingFrame.size.width;
  28. }
  29. //实现可滚动
  30. [_scrollView setContentSize:CGSizeMake(workingFrame.origin.x, workingFrame.size.height / 2)];
  31. [_scrollView setContentOffset:CGPointMake(360 * int_current, 0)];
  32. //加载其余缩略图
  33. loadThread = [[NSThread alloc]initWithTarget:self selector:@selector(loadImages) object:nil];
  34. return 0;
  35. }

使用低分辨率图

仔细想想,其实没有必要第一时间加载全部图片的高清原图,事先存好每张图配套的低分辨率图,用空间换时间。

先加载所有的图片的低分辨率图, 当用户翻阅到某一张图片时, 即时的加载原始尺寸的高清无码大图. 过程优化为:

多线程任务

即使是这样,当照片数量达到一定量时,需要消耗的时间也并非毫秒级,体验无法领人满意,  页面跳转时仍然会出现卡顿现象。

于是考虑使用多线程来进一步拆分任务, 执行跳转的同时再后台执行加载低分辨率图的步骤.

优化快速翻阅体验

通过这样的拆分,可以实现立即跳转,体验满意。但是翻阅浏览时,当用户很快左右滑动时, 出现黑屏的几率很高, 因为加载低分辨率图任务的线程可能还在进行大量IO操作,不能及时跟上。 为了完善它,要把加载低分辨率图的步骤再次分解,精益求精。 
在页面跳转时间允许的范围内,加载用户选定的那张图片的高清原图的同时,尽可能多的加载几张左右临近的图片的低分辨率图。

如何加载其余的低分辨率图?

以用户点击选定的那张图为中心向两边加载, 直接想应该是两个线程一左一右的加载,再想想左右一起加载其实可以是一个循环, 免了再开线程的那些耗费了。

  1. -(BOOL)loadImages
  2. {
  3. for (int i = int_current - 10, j = int_current + 10 ; !( i < 0 &&  int_total - 1 < j); --i, ++j) {
  4. if (!(i < 0)) {
  5. WQPhoto *photo_pre = [_scrollView.subviews objectAtIndex:i];
  6. WQAlbumPhoto *photoPre = [albumObject._photos objectAtIndex:i];
  7. [photo_pre setImage:photoPre.thumbnail4view];
  8. }
  9. if (!(int_total - 1 < j)) {
  10. WQPhoto *photo_next = [_scrollView.subviews objectAtIndex:j];
  11. WQAlbumPhoto *photoNext = [albumObject._photos objectAtIndex:j];
  12. [photo_next setImage:photoNext.thumbnail4view];
  13. }
  14. }
  15. return YES;
  16. }

最后还一个砍儿

尽量减少内存占用.  因为原始图片要比低分辨率图大很多, 所以当用户从一张图片翻阅到另一张图片时,  当前图片加载为原始尺寸的高清大图, 而原来那张就被替换为低分辨率图了。 虽然读写次数增多了, 但内存确实省了不少。

实话说,市场上不少相册类的app, 翻阅时都会有卡顿的跳跃感,呵呵……

P.S.  下次总结讨论下,独立开发者如何不花一分钱的推广,最终实现盈利:

欢迎交流

时间: 2024-10-29 10:45:44

iOS开发——加载、滑动翻阅大量图片解决方案详解的相关文章

phpcms加载系统类与加载应用类之区别详解

<?php 1. 加载系统类方法load_sys_class($classname, $path = ''", $initialize = 1)系统类文件所在的文件路径:/phpcms/libs/classes/文件夹下参数说明:@param string $classname 类名@param string $path 扩展地址@param intger $initialize 是否初始化 例子:如要调用系统Form类的生成验证码函数:checkcode() ,看下面例子pc_base:

iOS开发&gt;学无止境 - Cell异步图片加载优化,缓存机制详解

作者:勤奋的笨老头 网址:http://www.jianshu.com/p/02ab2b74c451 最近研究了一下UITbleView中异步加载网络图片的问题,iOS应用经常会看到这种界面.一个tableView上显示一些标题.详情等内容,在加上一张图片.这里说一下这种思路. 为了防止图片多次下载,我们需要对图片做缓存,缓存分为内存缓存于沙盒缓存,我们当然两种都要实现. 由于tableViewCell是有重用机制的,也就是说,内存中只有当前可见的cell数目的实例,滑动的时候,新显示cell会

IOS开发----加载地图之后显示为网格,不显示地图

加载地图之后,出现网格,经纬度已经加上了,但并没有地图显示.这时候要设置info.plist文件,右键,open AS------source code 在里面加上如下代码: <key>NSAppTransportSecurity</key><dict><key>NSAllowsArbitraryLoads</key><true/></dict><key>NSLocationWhenInUseUsageDesc

iOS Cell异步图片加载优化,缓存机制详解

最近研究了一下UITbleView中异步加载网络图片的问题,iOS应用经常会看到这种界面.一个tableView上显示一些标题.详情等内容,在加上一张图片.这里说一下这种思路. 为了防止图片多次下载,我们需要对图片做缓存,缓存分为内存缓存于沙盒缓存,我们当然两种都要实现.由于tableViewCell是有重用机制的,也就是说,内存中只有当前可见的cell数目的实例,滑动的时候,新显示cell会重用被滑出的cell对象.这样就存在一个问题: 一般情况下在我们会在cellForRow方法里面设置ce

iOS开发——高级特性&amp;Runtime运行时特性详解

Runtime运行时特性详解 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的动态特性,使这门古老的语言焕发生机.主要内容如下: 引言 简介 与Runtime交互 Runtime术语 消息 动态方法解析 消息转发 健壮的实例变量(Non Fragile ivars) Objective-C Associated Objects Method Swizzling 总结 引言 曾经觉得Objc特别方便上手,面对着 Cocoa 中大量

IOS开发UI篇之tableView 的用法详解

1.我们知道tableView是IOS中的高级视图,其继承与ScrollView,故我们知道他有具有ScrollView的所有功能.而且还扩展了许多.当然在这里就不一一介绍了. 2.tableView的表现格式分两种Plain和Grouped两种风格 3.tableView的两种代理类delegate和dataSource.这两种代理至关重要,我们在做tableView和这些代理是分不开的. 4.代理中比较常用的代理方法: (1)dataSource的两个必须使用的代理 @required //

iOS开发——KVO/KVC&amp;OC与Swift篇详解

Swift中使用KVC和KVO的类都必须必须继承自NSObject KVC key-value coding 是1种间接访问对象的机制 key的值就是属性名称的字符串,返回的value是任意类型,需要自己转化为需要的类型 KVC主要就是两个方法 (1)通过key设置对应的属性 (2)通过key获得对应的属性 举例 class TestForKVC:NSObject{ var hwcCSDN = "hello world" } var instance = TestForKVC() va

图片延时加载jquery.inview.js用法详解

我们在网站上总能见到这样的效果,若是有图片,图片都是先用loading加载一小段时间,然后紧接着出来要显示的图片,即效果如下: v2_loading.gif,几秒钟时间过渡到v2_pic_01_s.jpg这样,这就是图片延时加载. 具体实现技术如下: 1)引入jquery库文件: 2)引入jquery.inview.min.js文件: 3)html结构: <a href="http://q.wan.com" target="_blank" title=&quo

iOS开发 ----- 加载动画之牛顿摆的实现

牛顿摆动画 自己看动画有一段时间了,但是还是不是很能理解其中的一些属性方法之类的东西,琢磨了一下午写了一个牛顿摆的动画,这里记录一下,一遍以后查看先上图 先说下思路 说下牛顿摆的大致运动过程 根据牛顿摆的原理,中间是不动得,只有两边在动 两边运动是一个以这条线的上方位原点,长为半径,然后做半圆运动 运动模式是先快后慢 当左边的摆下来的时候,右边的开始向上摆动,右边的摆下来的时候,左边的开始向上摆动,一直循环下去 这样的话,我们用CAShapeLayer来进行画图,然后用CAAnimation来实