感谢原文作者的分享
本文转载至 http://my.oschina.net/u/2406027/blog/735738

PYPhotoBrowser

GitHub地址:https://github.com/iphone5solo/PYPhotoBrowser

  • Framework with a simple method of rendering images.
  • 用法简单的呈现一组图片的框架。

    效果图

  • 图片已发布(网络图片浏览、流水布局)

  • 图片未发布(本地图片上传\发布\预览)

支持哪些状态

  • 已发布(网络图片浏览)

  • 未发布(本地图片上传\发布\预览)

支持哪些布局

  • 流水布局 、 线性布局

支持哪些手势

  • 单击 、双击 、捏合 、旋转拖拽侧滑

什么地方用到这个框架

  • 主要用于社交app,用于呈现一组图片
  • 以下是各个流行社交app的部分截图

     

依赖哪些第三方框架

  • 图片浏览依赖框架

    • MBProgressHUD
    • SDWebImage
    • DACircularProgress

PYPhotoBrowser框架的主要类

PYPhotosView(快速使用)



@interface PYPhotosView : UIScrollView

/** 代理 */
@property (nonatomic, weak) id<PYPhotosViewDelegate> delegate; /** 网络图片模型数组 */
@property (nonatomic, copy) NSArray *photos;
/** 网络图片地址数组(缩略图) */
@property (nonatomic, copy) NSArray *thumbnailUrls;
/** 网络图片地址数组(原图) */
@property (nonatomic, copy) NSArray *originalUrls;
/** 本地相册图片数组(默认最多为九张,当传入图片数组长度超过九张时,取前九张) */
@property (nonatomic, strong) NSMutableArray *images; /** 所有图片的状态(默认为已发布状态) */
@property (nonatomic, assign) PYPhotosViewState photosState;
/** 图片布局(默认为流水布局) */
@property (nonatomic, assign) PYPhotosViewLayoutType layoutType;
/** 图片分页指示类型(默认为pageControll。当图片超过九张,改为label显示) */
@property (nonatomic, assign) PYPhotosViewPageType pageType; /** 图片间距(默认为5) */
@property (nonatomic, assign) CGFloat photoMargin;
/** 图片的宽 (默认为70) */
@property (nonatomic, assign) CGFloat photoWidth;
/** 图片的高 (默认为70) */
@property (nonatomic, assign) CGFloat photoHeight; /** 每行最多个数(默认为3), 当图片布局为线性布局时,此设置失效 */
@property (nonatomic, assign) NSInteger photosMaxCol;
/** 当图片上传前,最多上传的张数,默认为9 */
@property (nonatomic, assign) NSInteger imagesMaxCountWhenWillCompose; /** 快速创建photosView对象 */
+ (instancetype)photosView;
/** photos : 保存图片链接的数组 */
+ (instancetype)photosViewWithThumbnailUrls:(NSArray *)thumbnailUrls originalUrls:(NSArray *)originalUrls;
/** images : 存储本地图片的数组 */
+ (instancetype)photosViewWithImages:(NSMutableArray *)images; /**
* thumbnailUrls : 保存图片(缩略图)链接的数组
* originalUrls : 保存图片(原图)链接的数组
* type : 布局类型(默认为流水布局)
*/
+ (instancetype)photosViewWithThumbnailUrls:(NSArray *)thumbnailUrls originalUrls:(NSArray *)originalUrls layoutType:(PYPhotosViewLayoutType)type; /**
* thumbnailUrls : 保存图片(缩略图)链接的数组
* originalUrls : 保存图片(原图)链接的数组
* maxCol : 每行最多显示图片的个数
*/
+ (instancetype)photosViewWithThumbnailUrls:(NSArray *)thumbnailUrls originalUrls:(NSArray *)originalUrls photosMaxCol:(NSInteger)maxCol; /** 根据图片个数和图片状态自动计算出PYPhontosView的size */
- (CGSize)sizeWithPhotoCount:(NSInteger)count photosState:(NSInteger)state; /**
* 刷新图片(未发布)
* images : 新的图片数组
*/
- (void)reloadDataWithImages:(NSMutableArray *)images; @end

PYPhotoBrowseView(自定义)


@protocol PYPhotoBrowseViewDelegate <NSObject> @optional /**
* 图片浏览将要显示时调用
*/
- (void)photoBrowseView:(PYPhotoBrowseView *)photoBrowseView willShowWithImages:(NSArray *)images index:(NSInteger)index;
/**
* 图片浏览已经显示时调用
*/
- (void)photoBrowseView:(PYPhotoBrowseView *)photoBrowseView didShowWithImages:(NSArray *)images index:(NSInteger)index;
/**
* 图片浏览将要隐藏时调用
*/
- (void)photoBrowseView:(PYPhotoBrowseView *)photoBrowseView willHiddenWithImages:(NSArray *)images index:(NSInteger)index;
/**
* 图片浏览已经隐藏时调用
*/
- (void)photoBrowseView:(PYPhotoBrowseView *)photoBrowseView didHiddenWithImages:(NSArray *)images index:(NSInteger)index;
/**
* 图片单击时调用
*/
- (void)photoBrowseView:(PYPhotoBrowseView *)photoBrowseView didSingleClickedImage:(UIImage *)image index:(NSInteger)index;
/**
* 图片长按时调用
*/
- (void)photoBrowseView:(PYPhotoBrowseView *)photoBrowseView didLongPressImage:(UIImage *)image index:(NSInteger)index; @end @protocol PYPhotoBrowseViewDataSource <NSObject> @required
/** 返回将要浏览的图片(UIImage)数组 */
- (NSArray *)imagesForBrowse; @optional
/** 返回默认显示图片的索引(默认为0) */
- (NSInteger)currentIndex; /** 默认显示图片相对于主窗口的位置 */
- (CGRect)frameFormWindow; /** 消失回到相对于住窗口的指定位置 */
- (CGRect)frameToWindow; @end @interface PYPhotoBrowseView : UIWindow <PYPhotoViewDelegate> /** 代理 */
@property (nonatomic, weak) id<PYPhotoBrowseViewDelegate> delegate;
/** 数据源代理 */
@property (nonatomic, weak) id<PYPhotoBrowseViewDataSource> dataSource; /** 用来浏览的图片(UIImage)数组 */
@property (nonatomic, copy) NSArray *images; /** 用来记录当前下标 */
@property (nonatomic, assign) NSInteger currentIndex; /**
* 浏览图片
*/
- (void)show; /**
* 隐藏
*/
- (void)hidden; @end

如何使用PYPhotoBrowser

  • 使用Cocoapods:

    • pod "PYPhotoBrowser"
    • 导入主头文件#import <PYPhotoBrowser.h>
  • 手动导入:
    • PYPhotoBrowser文件夹中的所有文件拽入项目中
    • 导入主头文件#import "PYPhotoBrowser.h"
    • 使用注意:如果项目本来就有依赖的第三方框架:MBProgressHUD、SDWebImage、DACircularProgress就不必重复导入, 如果没有,选择Dependency文件夹中,项目不存在的框架拽入项目。

具体使用(详情见示例程序PYPhotosViewExample)

  • 已发布(网络图片浏览)

    示例代码:


// 1. 创建缩略图图片链接数组
NSMutableArray *thumbnailImageUrls = [NSMutableArray array];
// 添加图片(缩略图)链接
[thumbnailImageUrls addObject:@"http://ww3.sinaimg.cn/thumbnail/006ka0Iygw1f6bqm7zukpj30g60kzdi2.jpg"];
[thumbnailImageUrls addObject:@"http://ww1.sinaimg.cn/thumbnail/61b69811gw1f6bqb1bfd2j20b4095dfy.jpg"];
[thumbnailImageUrls addObject:@"http://ww1.sinaimg.cn/thumbnail/54477ddfgw1f6bqkbanqoj20ku0rsn4d.jpg"];
[thumbnailImageUrls addObject:@"http://ww4.sinaimg.cn/thumbnail/006ka0Iygw1f6b8gpwr2tj30bc0bqmyz.jpg"];
[thumbnailImageUrls addObject:@"http://ww2.sinaimg.cn/thumbnail/9c2b5f31jw1f6bqtinmpyj20dw0ae76e.jpg"];
[thumbnailImageUrls addObject:@"http://ww1.sinaimg.cn/thumbnail/536e7093jw1f6bqdj3lpjj20va134ana.jpg"];
[thumbnailImageUrls addObject:@"http://ww1.sinaimg.cn/thumbnail/75b1a75fjw1f6bqn35ij6j20ck0g8jtf.jpg"];
[thumbnailImageUrls addObject:@"http://ww2.sinaimg.cn/thumbnail/005NFHyQgw1f6bn8bha0eg308w0gib2d.gif"];
[thumbnailImageUrls addObject:@"http://ww1.sinaimg.cn/thumbnail/86afb21egw1f6bq3lq0itj20gg0c2myt.jpg"]; // 1.2 创建原图图片链接数组
NSMutableArray *originalImageUrls = [NSMutableArray array];
// 添加图片(原图)链接
[originalImageUrls addObject:@"http://ww3.sinaimg.cn/large/006ka0Iygw1f6bqm7zukpj30g60kzdi2.jpg"];
[originalImageUrls addObject:@"http://ww1.sinaimg.cn/large/61b69811gw1f6bqb1bfd2j20b4095dfy.jpg"];
[originalImageUrls addObject:@"http://ww1.sinaimg.cn/large/54477ddfgw1f6bqkbanqoj20ku0rsn4d.jpg"];
[originalImageUrls addObject:@"http://ww4.sinaimg.cn/large/006ka0Iygw1f6b8gpwr2tj30bc0bqmyz.jpg"];
[originalImageUrls addObject:@"http://ww2.sinaimg.cn/large/9c2b5f31jw1f6bqtinmpyj20dw0ae76e.jpg"];
[originalImageUrls addObject:@"http://ww1.sinaimg.cn/large/536e7093jw1f6bqdj3lpjj20va134ana.jpg"];
[originalImageUrls addObject:@"http://ww1.sinaimg.cn/large/75b1a75fjw1f6bqn35ij6j20ck0g8jtf.jpg"];
[originalImageUrls addObject:@"http://ww2.sinaimg.cn/large/005NFHyQgw1f6bn8bha0eg308w0gib2d.gif"];
[originalImageUrls addObject:@"http://ww1.sinaimg.cn/large/86afb21egw1f6bq3lq0itj20gg0c2myt.jpg"]; // 2. 创建一个photosView
PYPhotosView *photosView = [PYPhotosView photosViewWithThumbnailUrls:thumbnailImageUrls originalUrls:originalImageUrls]; // 3. 添加photosView
[self.view addSubview:photosView];
  • 未发布(本地图片上传\发布\预览)

    示例代码:


// 1. 创建本地图片数组
NSMutableArray *imagesM = [NSMutableArray array];
for (int i = 0; i < arc4random_uniform(4) + 1; i++) {
[imagesM addObject:[UIImage imageNamed:[NSString stringWithFormat:@"%02d", i + 1]]];
} // 2.1 设置本地图片
PYPhotosView *photosView = [PYPhotosView photosViewWithImages:imagesM]; // 3. 设置代理
photosView.delegate = self; // 4. 添加photosView
[self.view addSubview:photosView];
  • 自定义图片浏览(使用PYPhotoBrowseView类)

    示例代码:


// 1.创建自己定义的browseView
PYPhotoBrowseView *browseView = [[PYPhotoBrowseView alloc] init]; // 2.设置数据源和代理并实现数据源和代理方法
browseView.dataSource = self;
browseView.delegate = self; // 3.显示(浏览)
[browseView show]; // 实现数据源方法
#pragma mark - PYPhotoBrowseViewDataSource
// 返回将要浏览的图片(UIImage)数组
- (NSArray *)imagesForBrowse
{
NSMutableArray *imagesM = [NSMutableArray array];
for (int i = 0; i < 6 + 1; i++) {
[imagesM addObject:[UIImage imageNamed:[NSString stringWithFormat:@"%02d", i + 1]]];
}
return imagesM;
} // 返回默认显示图片的下标(默认为0)
- (NSInteger)currentIndex
{
return 2;
} // 返回从窗口的哪个位置开始显示(注意:frame是相当于window)
- (CGRect)frameFormWindow
{
return CGRectZero;
} // 返回消失到窗口的哪个位置(注意:frame是相当于window)
- (CGRect)frameToWindow
{
return CGRectMake(100, 300, 200, 200);
} // 实现代理方法
#pragma mark PYPhotoBrowseViewDelegate
- (void)photoBrowseView:(PYPhotoBrowseView *)photoBrowseView didSingleClickedImage:(UIImage *)image index:(NSInteger)index
{
NSLog(@"图片单击时调用");
// 关闭浏览
[photoBrowseView hidden];
}

自定义photosView

通过设置photosView的对象属性值即可修改

  • 设置布局类型(默认为流水布局)
// 设置布局为线性布局
photosView.layoutType = PYPhotosViewLayoutTypeLine;
  • 设置分页指示类型(默认为pageControll指示器)
// 设置指示类型为文本指示
photosView.pageType = PYPhotosViewPageTypeLabel;
  • 设置图片间距(默认为5)
// 设置图片间距为10
photosView.photoMargin = 10;
  • 设置图片大小(默认70*70)
// 设置图片的宽(width)
photosView.photoWidth = 100;
// 设置图片的高(height)
photosView.photoHeight = 60;
  • 设置每行图片最多个数(默认为3个)
// 设置图片最多列数
photosView.photosMaxCol = 6;
  • 设置图片上传前,最多上传的张数(默认为9)
// 设置图片最多上传的张数
photosView.imagesMaxCountWhenWillCompose = 15;

期待

  • 如果您在使用过程中有任何问题,欢迎直接加我QQ:499491531联系,很乐意为您解答任何相关问题!
  • 与其给我点star,不如向我狠狠地抛来一个BUG!
  • 如果感兴趣的小伙伴想要参与这个项目的维护,可以随时联系我或者直接pull request!
  • 如果您想要更多的接口来自定义,欢迎issue me!我会根据大家的需求提供更多的接口!

高仿QQ、微信效果的图片浏览器(支持原图和缩略图、多种手势、CocoaPods)的更多相关文章

  1. iOS天气动画、高仿QQ菜单、放京东APP、高仿微信、推送消息等源码

    iOS精选源码 TYCyclePagerView iOS上的一个无限循环轮播图组件 iOS高仿微信完整项目源码 想要更简单的推送消息,看本文就对了 ScrollView嵌套ScrolloView解决方 ...

  2. 高仿QQ即时聊天软件开发系列之三登录窗口用户选择下拉框

    上一篇高仿QQ即时聊天软件开发系列之二登录窗口界面写了一个大概的布局和原理 这一篇详细说下拉框的实现原理 先上最终效果图 一开始其实只是想给下拉框加一个placeholder效果,让下拉框在未选择未输 ...

  3. 高仿QQ即时聊天软件开发系列之二登录窗口界面

    继上一篇高仿QQ即时聊天软件开发系列之一开端之后,开始做登录窗口 废话不多说,先看效果,只有界面 可能还有一些细节地方没有做,例如那个LOGO嘛,不要在意这些细节 GIF虽短,可是这做起来真难,好吧因 ...

  4. 安卓高仿QQ头像截取升级版

    观看此篇文章前,请先阅读上篇文章:高仿QQ头像截取: 本篇之所以为升级版,是在截取头像界面添加了与qq类似的阴影层(裁剪区域以外的部分),且看效果图:   为了适应大家不同需求,这次打了两个包,及上图 ...

  5. 高仿QQ头像截取

    花费了半天时间,把 仿QQ头像截取的方法整理了下,并制作了一个demo以供大家参考,基本上实现了qq中我的资料界面上(包括背景透明化,上滑标题栏显示,下拉隐藏等)的大致效果,先上图看效果吧: 支持的功 ...

  6. Android 高仿QQ滑动弹出菜单标记已读、未读消息

    在上一篇博客<Android 高仿微信(QQ)滑动弹出编辑.删除菜单效果,增加下拉刷新功能>里,已经带着大家学习如何使用SwipeMenuListView这一开源库实现滑动列表弹出菜单,接 ...

  7. 史上最简单,一步集成侧滑(删除)菜单,高仿QQ、IOS。

    重要的话 开头说,not for the RecyclerView or ListView, for the Any ViewGroup. 本控件不依赖任何父布局,不是针对 RecyclerView. ...

  8. Android实现高仿QQ附近的人搜索展示

    本文主要实现了高仿QQ附近的人搜索展示,用到了自定义控件的方法 最终效果如下 1.下面展示列表我们可以使用ViewPager来实现(当然如果你不觉得麻烦,你也可以用HorizontalScrollVi ...

  9. 高仿QQ即时聊天软件开发系列之一开端

    前段时间在园子里看到一个大神做了一个GG2014IM软件,仿QQ的,那感觉···,赶快下载源码过来试试,还真能直接跑起来,效果也不错.但一看源码,全都给封装到了ESFramework里面了,音视频那部 ...

随机推荐

  1. JAVA自学笔记20

    JAVA自学笔记20 1.递归: 1)方法定义中定义中调用方法本身的现象 2)要有出口,否则就是死递归 次数不能太多.否则内存将溢出 构造方法不能递归使用 //斐波那契数列:1,1,2,3,5,8,1 ...

  2. .Net core下的配置设置(一)——Configuration

    ASP.NET Core 中提供了一个Configuration 包,用以应用配置基于配置提供程序建立的键值对.这里以json文件配置的方式,简单的介绍一下它的用法. 首先定义一个配置文件appset ...

  3. Python3 与 NetCore 基础语法对比(Function专栏)

    Jupyter最新排版:https://www.cnblogs.com/dotnetcrazy/p/9175950.html 昨晚开始写大纲做demo,今天牺牲中午休息时间码文一篇,希望大家点点赞 O ...

  4. DBS:CUPhone

    ylbtech-DBS:CUPhone 1.返回顶部 1. USE master GO -- Drop the database if it already exists IF EXISTS ( SE ...

  5. [rtsp]海康IPC监控摄像头远程外网监控配置(DDNS)

        本来这个DDNS服务正是我想要的,但是配置了之后海康提示不再提供这个服务了,以后统一使用萤石云了,看来有必要去学习下萤石开放平台的api,看都提供哪些服务. 海康威视网络摄像机出厂的默认IP地 ...

  6. 关于expect的实战总结

    如何从机器A上ssh到机器B上,然后执行机器B上的命令?如何使之自动化完成?看完下面的文章你就明白了 一.安装 expect 是基于tcl 演变而来的,所以很多语法和tcl 类似 sudo apt-g ...

  7. GitHub删除已有仓库

    之前都只是创建,还没试过删除,讲道理,如果第一次找删除按钮,还是有点小曲折的,特记录如下: 1.先找到你要删除的仓库 2.点进去,到具体项目地址,找到setting 3.点进去,一直往下翻,会看到红色 ...

  8. 分析轮子(九)- Cloneable.java

    注:玩的是JDK1.7版本 一:Cloneable.java 接口也是标记接口,所以,它没有任何方法和属性,实现此接口表示的意思是:可以调用 Object.java 类的 clone() 方法,进行简 ...

  9. css 定位(fixed > absolute > relative)与层级zIndex 的权限认知

    原则1: fixed > absolute > relative原则2: zIndex 越高越牛逼,不管你是谁无视身份.原则3: 青出于蓝而胜于蓝,儿子永远比父亲强原则4: 平台很重要. ...

  10. Shell脚本编程(三):shell参数传递

    我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n.n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推…… 实例 以下实例我们向脚本传递三 ...