高仿微信和今日头条图片浏览器(LBPhotoBrowser)

LBPhotoBrowser

一个使用简单的图片浏览器, 实现类似微信和今日头条的图片浏览效果

github地址:https://github.com/tianliangyihou/LBPhotoBrowser (包含demo) 如果喜欢的话记得点个star😝

目前已更新至V2.2,新增以下内容:

支持通过collectionView展示本地和网络图片(详情可在github查看demo)

概览(Overview)

/**
控件的基本结构
|--------------LBTapDetectingImageView(继承自UIImageView)----------| (最上层)
|---------------LBZoomScrollView(继承自UIScrollView)------------------------|
|---------------LBPhotoCollectionViewCell(继承自UICollectionViewCell)--------|
|---------------UICollectionView--------------------------------------------|
|---------------LBPhotoBrowserView(继承自UIWindow)------------------------|(最下层)
*/

LBPhotoBrowser对gif图片的加载机制:

LBPhotoBrowser对gif的播放提供了两种方式:

(1)采用系统的 + (nullableUIImage*)animatedImageWithImages:(NSArray *)images duration:(NSTimeInterval)durationNS_AVAILABLE_IOS(5_0);

(2)自定义gif的播放,具体步骤如下:

   * 获取当前手机可以利用的内存和当前展示的gif图片每帧图片加载到内存占用的大小,以取得当前内存可以加载gif的最大帧数.
     最大加载帧数 = 可利用内存 /  每帧图片的大小.
     
   * 使用CADisplayLink作为定时器,开始展示当前帧的图片
   
   * 获取当前帧的展示时间,展示完毕,切换下一帧图片.当在展示当前帧的图片的时候, 异步线程(自定义NSOperation)去取下一帧的图片,以供当前帧的图片展示
     完毕后,直接从缓存的buffer(字典)中读取.
     
   * 当gif图片的帧数大于当前内存适合加载的帧数的时候,buffer(字典)会不断的移除已展示过的图片,来确保加载到内存中的图片数稳定.
     如果小于可加载的最大帧数,直接全部加载到内存,节省CPU.
     
   * LBPhotoBrowser为了保证较低的CPU消耗,即使在图片浏览器加载多张gif的时候,也会保证同一时间内,只会对一张gif进行处理,不会同时去解压多张gif图片.
   
   建议使用第二种加载方式 即 lowGifMemory = YES, 通过 LBPhotoBrowserManager 的 lowGifMemory 属性控制 
   
   当你加载的gif图片较多,并且gif的帧数也比较多,两种方式的差别会特别明显,方式2的优点也越明显.(不要使用模拟器测试)

LBPhotoBrowser对网络图片的预加载机制:

LBPhotoBrowser 将网络图片的加载分为两种:
  
 (1)缩略图和大图使用同一个url 不需要提供预加载
 
 (2)缩略图和大图使用不同的url 提供预加载  
 
    * 当点击图片,通过LBPhotoBrowser展示大图的过程中,LBPhotoBrowser会自动提前加载当前图片左右两张图片,以方便用户浏览
    
    * 当用户在滑动图片的过程中,LBPhotoBrowser会始终保持优先加载当前展示图片和当前展示图片左右两张的图片,并且停止离当前图片较远图片的加载
    
    * 当用户退出LBPhotoBrowser,停止所有图片的加载
   
   当你使用(1)展示图片的时候,请设置`LBPhotoBrowserManager`的`needPreloading` = `NO`. 
   
   注:
      缩略图: 当前展示给用户的图片
        大图: 点击缩略图后,使用LBPhotoBrowser展示给用户的图片

使用(Usage)

LBPhotoBrowser 支持本地图片和网络图片 以及gif的播放,下面四中效果详情可参考demo

效果1: 加载本地图片,支持相册中的gif的图片

effect0.gif
  NSMutableArray *items = [[NSMutableArray alloc]init];
  for (UIImageView *imageView in self.imageViews) {
        LBPhotoLocalItem *item = [[LBPhotoLocalItem alloc]initWithImage:imageView.image frame:imageView.frame];
        [items addObject:item];
    }
  [[LBPhotoBrowserManager defaultManager]showImageWithWebItems:items selectedIndex:tag fromImageViewSuperView:self.view];

效果2: 加载网络图片,实现类似微信的图片浏览效果,缩略图和大图使用不同的url

effect1.gif
 NSMutableArray *items = [[NSMutableArray alloc]init];
 for (int i = 0 ; i < cellModel.urls.count; i++) {
       LBURLModel *urlModel = cellModel.urls[i];
        UIImageView *imageView = cell.imageViews[i];
        LBPhotoWebItem *item = [[LBPhotoWebItem alloc]initWithURLString:urlModel.largeURLString frame:imageView.frame];
        item.placeholdImage = imageView.image;
        [items addObject:item];
     }
   [LBPhotoBrowserManager.defaultManager showImageWithWebItems:items selectedIndex:tag fromImageViewSuperView:cell.contentView].lowGifMemory = YES;

效果3: 加载网络图片,实现类似今日头条的图片浏览效果,缩略图和大图使用不同的url

effect2_new.gif
NSMutableArray *items = [[NSMutableArray alloc]init];
for (int i = 0 ; i < cellModel.urls.count; i++) {
      LBURLModel *urlModel = cellModel.urls[i];
       UIImageView *imageView = cell.imageViews[i];
       LBPhotoWebItem *item = [[LBPhotoWebItem alloc]initWithURLString:urlModel.largeURLString frame:imageView.frame placeholdImage:imageView.image placeholdSize:imageView.frame.size];
        [items addObject:item];
  }
 [LBPhotoBrowserManager.defaultManager showImageWithWebItems:items selectedIndex:tag fromImageViewSuperView:cell.contentView].lowGifMemory = YES;

效果4: 加载网络图片 缩略图和大图使用同一个url

effect3.gif
 NSMutableArray *items = [[NSMutableArray alloc]init];
 for (int i = 0 ; i < cellModel.urls.count; i++) {
        LBURLModel *urlModel = cellModel.urls[i];
        UIImageView *imageView = cell.imageViews[i];
         LBPhotoWebItem *item = [[LBPhotoWebItem alloc]initWithURLString:urlModel.largeURLString frame:imageView.frame];
         [items addObject:item];
     }
  [LBPhotoBrowserManager.defaultManager showImageWithWebItems:items selectedIndex:tag fromImageViewSuperView:cell.contentView].lowGifMemory = YES;
  [[LBPhotoBrowserManager defaultManager]addPhotoBrowserWillDismissBlock:^{
    // do something       
   }].needPreloading = NO;
      

提示(Tip)

关于图片展示过程中,关于status bar控制
对于status bar的处理,相比之前做了较大的优化
采用创建一个新的level 高于status bar 的window 覆盖在之前的window上
效果更佳流畅和自然 (上面展示效果的gif图片 是采用了之前版本的处理方式,如果感觉不流畅,请忽略)
保存gif图片的问题
由于 SDWebImage 返回的image只是这个gif图片的第一帧

1 当lowGifMemory = NO 的情况下,可以直接过
// 默认长按控件的回调
- (instancetype)addTitleClickCallbackBlock:(void(^)(UIImage *image,NSIndexPath *indexPath,NSString *title))titleClickCallBackBlock;
add 这个block 返回的image 进行保存

2 当lowGifMemory = YES的情况下,通过下面这个block返回的data进行保存, 这个也适合方式1
 [[SDImageCache sharedImageCache] queryCacheOperationForKey:currentUrl.absoluteString done:^(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType) {
    
 }];
使用 LBPhotoBrowser 的时候 当你需要添功能的时候 就尝试add Block, LBPhotoBrowser可以无限add block,同一个block add多次,后添加的生效

所以你可以这样写,可以更长_ ,当然也可以分开写

     [[[[LBPhotoBrowserManager.defaultManager addLongPressShowTitles:@[@"保存",@"识别二维码",@"取消"]]addTitleClickCallbackBlock:^(UIImage *image, NSIndexPath *indexPath, NSString *title) {
          // do somehting
      }]addPhotoBrowserWillDismissBlock:^{
          // do somehting
      }]addPhotoBrowserDidDismissBlock:^{
          // do somehting
      }];
关于SDWebImage加载gif图片的问题(sd_setImageWithURL):
当你在真机上运行当前版本的时候,你会发现展示gif的一个问题 => 拖动pop当前界面的时候,imageView上的图片不见了

这个是SDWebImage内部的一个方法导致的.

你可以在demo的style3中(右上角有个测试按钮)中找到原因和解决办法

LBPhotoBrowser的依赖
LBPhotoBrowser 只依赖于SDWebImage,本身实现了gif的解压和播放

相关(Relevant)

这是本人写的一个高仿今日头条的项目,目前还在完善中 部分已有的功能如下:

采用了RAC + MVVM 的方式

https://github.com/tianliangyihou/headlineNews
15149595695a4c72d13590a.gif

LBPhotoBrowser之前版本介绍: https://www.jianshu.com/p/00f4b7b20dc4 (简书) 当前版:v2.1

如果您使用过程中发现什么问题,请及时给我留言 或者 在github上issue me 期待和您一起改进LBPhotoBrowser https://github.com/tianliangyihou/LBPhotoBrowser

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,427评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 春节假期,腊月三十,在家。 父母在准备着春节的午饭和年夜饭,计划着春节后亲戚朋友串门的饭菜,也在盘算着假期结束后让...
    繁华未尽阅读 203评论 0 0
  • 昨天加入了读书会,这是继寒假以后的再次加入。曾对朋友说想抽离一阵子让自己轻装上阵。之前,对于一些工作有些烦恼,很多...
    一点点巧儿阅读 285评论 0 1
  • 不经意间,空气里已经开始带上了寒意。上午的云逐渐散去,一块块蓝天透露出来,阳光甚好。 不愿辜负好时光,背包出门,在...
    木之行道者阅读 304评论 0 2