UICollectionView简介
UICollectionView是iOS6添加的一个控件,是一种新的数据展示方式,简单来说可以把他理解成多列的UITableView,最简单的UICollectionView就是一个GridView,可以以多列的方式将数据进行展示。
标准的UICollectionView包含三个部分,它们都是UIView的子类:
Cells 用于展示内容的主体,对于不同的cell可以指定不同尺寸和不同的内容
Supplementary Views 追加视图,可以理解为每个Section的Header或者Footer,用来标记每个section的view
Decoration Views 装饰视图 这是每个section的背景
实现一个简单的UICollectionView
实现一个UICollectionView和实现一个UITableView基本没有什么大区别,它们都同样是datasource+delegate
基本的UICollectionViewDataSource提供
<pre><code>
-numberOfSectionsInCollection: //section的数量
-collectionView:numberOfItemsInSection: //某个section里有多少个item
-collectionView:cellForItemAtIndexPath: // 对于某个位置应该显示什么样的cell
-collectionView:viewForSupplementaryElementOfKind:atIndexPath: //提供Supplementary View
</code></pre>
与UITableView中的情况一致,UICollectionView也需要对Cell进行重用,在iOS5中,Apple对UITableView的重用做了简化,以往要写类似这样的代码:
<pre><code>
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MY_CELL_ID"];
if (!cell) {
cell = [[UITableViewCell alloc] init];
}
//配置cell,blablabla
return cell
</code></pre>
在iOS5以后如果我们在TableView向数据源请求数据之前使用-registerNib:forCellReuseIdentifier:方法为@“MYCELLID"注册过nib的话,就可以省下每次判断并初始化cell的代码,要是在重用队列里没有可用的cell的话,runtime将自动帮我们生成并初始化一个可用的cell,还有以下类似方法
<pre><code>
(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);
(void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
(void)registerNib:(UINib *)nib forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
(void)registerClass:(Class)aClass forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
</code></pre>
同样的 UICollectionView也有类似的方法
<pre><code>
(void)registerClass:(Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
(void)registerNib:(UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;
(void)registerClass:(Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;
(void)registerNib:(UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier;
</code></pre>
基本的UICollectionViewDelegate提供与数据无关的view的外形,用户交互之类:
cell的高亮
cell的选中状态
可以支持长按后的菜单
关于用户交互,UICollectionView也做了改进。每个cell现在有独立的高亮事件和选中事件的delegate,用户点击cell的时候,现在会按照以下流程向delegate进行询问:
<pre><code>
-collectionView:shouldHighlightItemAtIndexPath: // 是否应该高亮?
-collectionView:didHighlightItemAtIndexPath: //如果1答是,那么高亮
-collectionView:shouldSelectItemAtIndexPath: //无论1结果如何,都询问是否可以被选中?
-collectionView:didUnhighlightItemAtIndexPath: // 如果1答是,那么现在取消高亮
-collectionView:didSelectItemAtIndexPath: // 如果3答是,那么选中cell
</code></pre>
Cell
UICollectionViewCell结构比较简单, 由上至下
首先是cell本身作为容器view
然后是一个大小自动适应整个cell的backgroundView,用作cell平时的背景
再其上是selectedBackgroundView,是cell被选中时的背景
最后是一个contentView,自定义内容应被加在这个view上
UICollectionViewLayout
这是UICollectionView和UITableView最大的不同。UICollectionViewLayout负责了将各个cell、Supplementary View和Decoration Views进行组织,为它们设定各自的属性。在展示之前,一般需要生成合适的UICollectionViewLayout子类对象,并将其赋予CollectionView的collectionViewLayout属性。
SDK为我们提供了一个最简单可能也是最常用的默认layout对象,UICollectionViewFlowLayout。Flow Layout简单说是一个直线对齐的layout,最常见的Grid View形式即为一种Flow Layout配置:
首先一个重要的属性是itemSize,它定义了每一个item的大小。通过设定itemSize可以全局地改变所有cell的尺寸,如果想要对某个cell制定尺寸,可以使用-collectionView:layout:sizeForItemAtIndexPath:方法。
间隔 可以指定item之间的间隔和每一行之间的间隔,和size类似,有全局属性,也可以对每一个item和每一个section做出设定:
<pre><code>
@property (CGSize) minimumInteritemSpacing
@property (CGSize) minimumLineSpacing
-collectionView:layout:minimumInteritemSpacingForSectionAtIndex:
-collectionView:layout:minimumLineSpacingForSectionAtIndex:
</code></pre>
滚动方向 由属性scrollDirection确定scroll view的方向,将影响Flow Layout的基本方向和由header及footer确定的section之间的宽度
UICollectionViewScrollDirectionVertical
UICollectionViewScrollDirectionHorizontal
Header和Footer尺寸 同样地分为全局和部分。需要注意根据滚动方向不同,header和footer的高和宽中只有一个会起作用。垂直滚动时section间宽度为该尺寸的高,而水平滚动时为宽度起作用,如图。
<pre><code>
@property (CGSize) headerReferenceSize
@property (CGSize) footerReferenceSize
-collectionView:layout:referenceSizeForHeaderInSection:
-collectionView:layout:referenceSizeForFooterInSection:
</code></pre>
缩进
<pre><code>
@property UIEdgeInsets sectionInset;
-collectionView:layout:insetForSectionAtIndex:
</code></pre>
通过自定义Layout可以实现各种nb布局,基本上常见的类似的第三方开源控件效果都可以实现,比如瀑布流、coverFlow,下面实现一个基本的瀑流效果