一、功能强大的集合视图
UICollectionView是一种新的数据展示视图,最最基本的集合视图类似于UITableView,就是多行多列展示数据,之前试着用UITableView实现过多行多列展示图片,不过效果一般而且bug较多。ios开发——用UITableView展示多行多列图片
而UICollectionView出现后,这种效果就非常非常容易了,不但如此,之前的各种开源社区里一些瀑布流也变得非常简单。不过,正如刚才所说,这都是UICollectionView最最基本的形式,实际上,它真正强大的地方在于完全的自定义。你可以继承UICollectionViewLayout类来创建自己的Layout,进而仅仅通过相对简短的代码来实现相当强大的效果。例如苹果官方的实例代码中的特效:
很熟悉吧?这正是以前开源社区里的大神们封装的各种自定义视图,现在,通过UICollectionViewLayout我们也能结合上CAAnimation实现这种带炫酷动画的视图了。
二、致谢
本文的诞生来自于最近想写一个课程表,需要用到UICollectionView,特意去网上看了资料。之前我对集合视图的认识仅仅限于多行多列的TableView,后来看了@onevcat的博客后才知道这个视图的强大之处。本文相当于对他的博客的学习笔记。
三、一些基本概念
一般来说,一个完整的UICollectionView包括以下三个部分:
cell——相当于表格视图里的cell,需要通过dataSource来为其指定数据源,主要功能就是展示图片或其他信息,以及处理交互。
Supplementary Views——附加视图,类比表格视图里的header和footer,可有可无,起展示附加信息的作用。
Decoration Views——装饰视图,指cell的背景装饰,比如iBooks应用里的背景书架
四、Data Source
如果是实现一个最基本的UICollectionView,也就是像上图一样的一个多行多列的表格,那么过程就与实现UITableView一样了,为其制定数据源并实现相应方法即可:
<span style="font-size:18px;">?-numberOfSectionsInCollection: 返回有多少Section,可以理解为多少行 ?-collectionView:numberOfItemsInSection: 返回每个Section中有多少内容,可以理解为多少列 -collectionView:cellForItemAtIndexPath: 返回每个Item,在该方法中进行复用、构造、初始化等操作。</span>
另外也可以指定Supplementary Views
-collectionView:viewForSupplementaryElementOfKind:atIndexPath:
但是没有制定Decoration Views的方法,因为这个被移到了UICollectionViewLayout中单独实现。
和UITableView一样,只有列数和返回Item的那两个方法是required,其他的是optional,但是一般来说我们通过实现前三个方法可以保证一个简单地UICollectionView正常工作。
五、关于复用
在UITableView中,我们可以这样写来实现cell的复用
<span style="font-size:18px;">- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *cellId = @"cellID"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId]; } return cell; }</span>
即直接取复用cell,如果不存在就新建一个,然而,这种方法在UICollectionView中是行不通的,因为没有
- dequeueReusableCellWithIdentifier:这样的方法,只有一个
- dequeueReusableCellWithReuseIdentifier: forIndexPath:方法,这个方法要求必须提前用ReuseIdentifier注册cell。因此在使用之前必须通过以下四种方法之一来注册。
<span style="font-size:18px;">-registerClass:forCellWithReuseIdentifier: -registerClass:forSupplementaryViewOfKind:withReuseIdentifier: -registerNib:forCellWithReuseIdentifier: -registerNib:forSupplementaryViewOfKind:withReuseIdentifier:</span>
六、交互处理——Delegate
和UITableView一样,可以在Delegate中处理单元格cell的点击事件、设置高亮与选择状态等,还支持长按相应菜单。
稍有不同的是,在UICollectionView中可以单独处理单元格的这些事件,而不是统一处理。具体来说,在方法中多了IndexPath参数,例如:
<span style="font-size:18px;">-?collectionView:shouldHighlightItemAtIndexPath: -?collectionView:didHighlightItemAtIndexPath: -?collectionView:shouldSelectItemAtIndexPath: </span>
这样处理起来就更加灵活了。
七、UICollectionViewLayout与UICollectionViewFlowLayout
这里顺带提一下Layout类,这个是UICollectionView的与UITableView最大的不同之处,也是让UICollectionView功能那么强大的精髓之处,因此这个会单独拿一篇博文来记录。
UICollectionViewLayout决定了我们的UICollectionView是如何被展示到屏幕上的,它决定着cell、supplementary views和decorator view的位置、大小、透明度、形状、层级关系等等。再生成UICollectionView时要制定其Layout,这里比较常见的做法是继承UICollectionViewLayout类并自定义布局,或者使用Apple提供给我们的最基本的布局——UICollectionViewFlowLayout,也就是我们最常见的Gird
View的形式。
在Flow Layout 中,有以下几个重要属性:
—itemSize 决定着每个cell的大小
—minimumInteritemSpacingcell与cell间的最小间距。为什么说是最小呢?就比如非常流行的瀑布流,每个图片的大小是不一样的,因此这个属性决定了它们之间的最小间距界限。
—minimumLineSpacing行与行之间的最小间距
—scrollDirection
滚动方向,与UITableView一样,UICollectionView也是继承自UIScrollView,因此通过这个属性为其制定滚动的方向。
—headerReferenceSize、footerReferenceSizeheader和footer的宽高,这两个属性只有一个会起作用,这决定与上一个属性,滚动方向的设定。水平滚动时宽度起作用,竖直滚动时高度起作用
—sectionInset
缩进,可以理解为cell的边界的“扩充”部分。
需要注意的是,上述属性全部都是全局的,也就是说对所有的cell都起作用,如果想单独设置,Flow Layout提供了对应的方法:
<span style="font-size:18px;">-collectionView:layout:sizeForItemAtIndexPath: -collectionView:layout:minimumInteritemSpacingForSectionAtIndex: -collectionView:layout:minimumLineSpacingForSectionAtIndex: -collectionView:layout:referenceSizeForHeaderInSection: -collectionView:layout:referenceSizeForFooterInSection: -collectionView:layout:insetForSectionAtIndex:</span>
八、总结
要实现一个UICollectionView,必须要做的工作是dataSource和layout的实现,其中dataSource与UITableView类似,layout部分Apple已经提供了一个Flow Layout作简单的瀑布流展示,而处理用户交互就需要delegate,在UICollectionView中cell的几乎所有的属性和交互都可以通过方法来单独处理。