iOS之UICollectionView详解
UICollectionView是一种类似于UITableView但又比UITableView功能更强大、更灵活的视图,这是源于它将UICollectionView对cell的布局交给了UICollectionViewLayout,而且允许用户自定义layout来进行布局。
当UICollectionView显示内容时,先从Data source(数据源)获取cell,然后交给UICollectionView。再从UICollectionViewLayout获取对应的layout attributes(布局属性)。最后,根据每个cell对应的layout attributes(布局属性)来对cell进行布局,生成了最终的界面。而用户交互的时候,都是通过Delegate来进行交互。当然,上面只是布局cell,但是UICollectionView内部还有Supplementary View和Decoration View,也可以对其进行布局。
上面,我们了解了UICollectionView的工作流程,我们将UICollectionView分成视图、数据源和代理方法、UICollectionViewLayout三块来介绍。
一、视图
UICollectionView上面显示内容的视图有三种Cell视图、Supplementary View和Decoration View。
Cell视图
CollectionView中主要的内容都是由它展示的,它是从数据源对象获取的。
Supplementary View
它展示了每一组当中的信息,与cell类似,它是从数据源方法当中获取的,但是与cell不同的是,它并不是强制需要的。例如flow layout当中的headers和footers就是可选的Supplementary View。
Decoration View
这个视图是一个装饰视图,它没有什么功能性,它不跟数据源有任何关系,它完全属于layout对象。
二、数据源和代理方法
1、注册cell或者Supplementary View使其重用
在使用数据源返回cell或者Supplementary View给collectionView之前,我们必须先要注册,用来进行重用。
- registerClass: forCellWithReuseIdentifier:
- registerNib: forCellWithReuseIdentifier:
- registerClass: forSupplementaryViewOfKind: withReuseIdentifier:
- registerNib: forSupplementaryViewOfKind: withReuseIdentifier:
显而易见,前面两个方法是注册cell,后两个方法注册Supplementary View。其中,注册的方式有两种,第一种是直接注册class,它重用的时候会调用[[UICollectionView alloc] init]这样的初始化方法创建cell;另外一种是注册nib,它会自动加载nib文件。
注册的之后,我们如何重用?
在数据源方法当中返回 cell 或者 Supplementary view 的方法当中通过dequeueReusableCellWithReuseIdentifier:forIndexPath: 或者dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath: 方法获取cell或者Supplementary View。
示例代码:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellReuseIdentify forIndexPath:indexPath];
cell.backgroundColor = [UIColor lightGrayColor];
cell.textLabel.text = [NSString stringWithFormat:@"(%zd,%zd)", indexPath.section, indexPath.row];
return cell;
}
2、数据源方法
数据源方法与UITableView类似,主要有:
- numberOfSectionsInCollectionView:
- collectionView: numberOfItemsInSection:
- collectionView: cellForItemAtIndexPath:
- collectionView: viewForSupplementaryElementOfKind: atIndexPath:
与UITableView不同的是多加了返回Supplementary view数据源方法。
3、代理方法
数据源为UICollectionView提供数据相关的内容,而代理则主要负责用户交互、与数据无关的视图外形。主要分成两部分:
1、通过调用代理方法,管理视图的选中、高亮
- collectionView:shouldDeselectItemAtIndexPath:
- collectionView:didSelectItemAtIndexPath:
- collectionView:didDeselectItemAtIndexPath:
- collectionView:shouldHighlightItemAtIndexPath:
- collectionView:didHighlightItemAtIndexPath:
- collectionView:didUnhighlightItemAtIndexPath:
2、长按cell,显示编辑菜单 当用户长按cell时,collection view视图会显示一个编辑菜单。这个编辑菜单可以用来剪切、复制和粘贴cell。不过,要显示这个编辑菜单需要满足很多条件:
- 代理对象必须实现下面三个方法:
collectionView:shouldShowMenuForItemAtIndexPath:collectionView:canPerformAction:forItemAtIndexPath:withSender:collectionView:performAction:forItemAtIndexPath:withSender: - 对于指定要编辑的cell,
collectionView:shouldShowMenuForItemAtIndexPath:方法需要返回YES collectionView:canPerformAction:forItemAtIndexPath:withSender:方法中,对于剪切、复制、粘贴三种action至少有一个返回YES。其实,编辑菜单是有很多种action的,但是对于UICollectionView来说,它仅仅支持的剪切、复制、粘贴三个,所以说这个代理方法至少支持这三种的一种。剪切、复制、粘贴的方法名是:
cut:copy:paste:当上面的条件都满足了,用户就可以长按cell显示出编辑菜单,然后选择对应的action,从而就会回调delegate的collectionView:performAction:forItemAtIndexPath:withSender: 方法去做对应的事情。
当我们想控制编辑菜单仅仅显示复制和粘贴时,我们就可以在collectionView:canPerformAction:forItemAtIndexPath:withSender:方法中进行操作,具体请见下面代码:
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender{
if ([NSStringFromSelector(action) isEqualToString:@"copy:"]
|| [NSStringFromSelector(action) isEqualToString:@"paste:"])
return YES;
return NO;
}
三、UICollectionViewLayout
UICollectionViewLayout 是UICollectionView比UITableView更强大原因,它是UICollectionView的精髓,它通过 UICollectionViewLayoutAttributes 类来管理 cell 、 Supplementary View 和 Decoration View 的 位置 、transform 、 alpha 、 hidden 等等。
UICollectionViewLayout这个类只是一个基类,我们给UICollectionView使用的都是它的 子类 。系统为我们提供了一个最常用的layout为UICollectionViewFlowLayout ,我们可以使用它制作 grid view 。当UICollectionViewLayout满足不了我们的需求时,我们可以 子类化UICollectionViewLayout 或者 自定义layout ,这个内容放到我下一篇当中。
下面,我们来看看怎么使用UICollectionViewFlowLayout。 使用UICollectionViewFlowLayout之前,我们来了解它内部常用的属性:
//同一组当中,行与行之间的最小行间距,但是不同组之间的不同行cell不受这个值影响。
@property (nonatomic) CGFloat minimumLineSpacing;
//同一行的cell中互相之间的最小间隔,设置这个值之后,那么cell与cell之间至少为这个值
@property (nonatomic) CGFloat minimumInteritemSpacing;
//每个cell统一尺寸
@property (nonatomic) CGSize itemSize;
//滑动反向,默认滑动方向是垂直方向滑动
@property (nonatomic) UICollectionViewScrollDirection scrollDirection;
//每一组头视图的尺寸。如果是垂直方向滑动,则只有高起作用;如果是水平方向滑动,则只有宽起作用。
@property (nonatomic) CGSize headerReferenceSize;
//每一组尾部视图的尺寸。如果是垂直方向滑动,则只有高起作用;如果是水平方向滑动,则只有宽起作用。
@property (nonatomic) CGSize footerReferenceSize;
//每一组的内容缩进
@property (nonatomic) UIEdgeInsets sectionInset;
上面是UICollectionViewFlowLayout内部的属性,这些属性都是统一设置,若是统一设置无法满足需求,可以实现 UICollectionViewDelegateFlowLayout 方法,进行对应的设置。
了解了UICollectionViewFlowLayout主要属性,我们再来看看使用步骤:
1、生成一个UICollectionViewFlowLayout对象给collection view
2、通过itemSize来配置cell的宽和高
3、如果有需要通过设置minimumInteritemSpacing来设置每个cell之间的间距,通过minimumLineSpacing来设置同一组当中不同行之间cell的行距。
4、如果想要组头视图或者组尾视图,指定它们的大小
5、设置layout的滑动方向
6、如果统一设置无法满足需求,实现UICollectionViewDelegateFlowLayout方法来进行设置。
iOS之UICollectionView详解的更多相关文章
- iOS开发- UICollectionView详解+实例
本章通过先总体介绍UICollectionView及其常用方法,再结合一个实例,了解如何使用UICollectionView. UICollectionView 和 UICollectionViewC ...
- [转] iOS开发- UICollectionView详解+实例
本章通过先总体介绍UICollectionView及其常用方法,再结合一个实例,了解如何使用UICollectionView. UICollectionView 和 UICollectionViewC ...
- iOS开发——UI篇OC篇&UICollectionView详解+实例
UICollectionView详解+实例 实现步骤: 一.新建两个类 1.继承自UIScrollView的子类,比如HMWaterflowView * 瀑布流显示控件,用来显示所有的瀑布流数据 2. ...
- 转载]IOS LBS功能详解[0](获取经纬度)[1](获取当前地理位置文本 )
原文地址:IOS LBS功能详解[0](获取经纬度)[1](获取当前地理位置文本作者:佐佐木小次郎 因为最近项目上要用有关LBS的功能.于是我便做一下预研. 一般说来LBS功能一般分为两块:一块是地理 ...
- iOS中-Qutarz2D详解及使用
在iOS中Qutarz2D 详解及使用 (一)初识 介绍 Quartz 2D是二维绘图引擎. 能完成的工作有: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成 ...
- iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)
前言:一个路径可以包含由一个或者多个shape以及子路径subpath,quartz提供了很多方便的shape可以直接调用.例如:point,line,Arc(圆弧),Curves(曲线),Ellip ...
- iOS开发——Block详解
iOS开发--Block详解 1. Block是什么 代码块 匿名函数 闭包--能够读取其他函数内部变量的函数 函数变量 实现基于指针和函数指针 实现回调的机制 Block是一个非常有特色的语法,它可 ...
- iOS开发:详解Objective-C runTime
Objective-C总Runtime的那点事儿(一)消息机制 最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎 ...
- iOS应用开发详解
<iOS应用开发详解> 基本信息 作者: 郭宏志 出版社:电子工业出版社 ISBN:9787121207075 上架时间:2013-6-28 出版日期:2013 年7月 开本:16开 ...
随机推荐
- JavaScript跨域调用、JSONP、CORS与ASP.NET Web API[共8篇]
[第1篇] 同源策略与JSONP 浏览器是访问Internet的工具,也是客户端应用的宿主,它为客户端应用提供一个寄宿和运行的环境.而这里所说的应用,基本是指在浏览器中执行的客户端JavaScript ...
- Web Fundamentsals学习1-Multiple-Screen-Site
你的一个运行于多设备网站(Your First Multi-device Site) 遵循的步骤: 1.定义信息架构(information architecture)和页面结构(structure ...
- 关于SubSonic3.0未处理InvalidOperationException异常(关键字TOP附近有语法错误)的处理
早上在测试程序时,使用了Top这个属性,没想到马上抛出了个“未处理InvalidOperationException异常(关键字'TOP'附近有语法错误)”这个错误提示,见下图: 然后Debug一下, ...
- Lua 学习笔记(八)错误(error)
Lua所遇到的任何未预期条件都会引发一个错误.因此在发生错误时不能简单的崩溃或着退出,而是结束当前程序块并返回应用程序.当错误引发时进行恰当的处理是最合适的,然而这个阶段伴随着错误的捕获.错误的处理. ...
- 11.struts2文件上传
文件上传 1.上传单个文件 2.上传多个文件 1.上传单个文件 实现步骤: (1)导入一个Jar包:commons-io-1.3.2.jar.只所以要导入这个Jar包,是因为要用到一个工具类Fil ...
- Linux资源控制-CPU和内存
主要介绍Linux下, 如果对进程的CPU和内存资源的使用情况进行控制的方法. CPU资源控制 每个进程能够占用CPU多长时间, 什么时候能够占用CPU是和系统的调度密切相关的. Linux系统中有多 ...
- https问答篇
https问答 SSL和TLS有什么区别? 可以说,TLS是SSL的升级版本,SSL是网景公司设计的,为了最早期的网络安全而生,它的全名叫做"安全套接层".后来,IETF在1999 ...
- js的stopPropagation()、cancelBubble、preventDefault()、return false的分析
个人笔记,如有错误,望指出. 事件冒泡,举个列子: <li> <a href='http://www.baidu.com'>点击a</a> </li> ...
- 7.9 数据注解特性--ForeignKey
外键特性,可以应用到类的属性中.Code-First默认的约定,对外键属性来说,假定外键属性的名称和主键属性是匹配的. 我们看一下,下面的代码: using System; using System. ...
- Rafy 领域实体框架设计 - 重构 ORM 中的 Sql 生成
前言 Rafy 领域实体框架作为一个使用领域驱动设计作为指导思想的开发框架,必然要处理领域实体到数据库表之间的映射,即包含了 ORM 的功能.由于在 09 年最初设计时,ORM 部分的设计并不是最重要 ...