UICollectionView内容整理
1、UICollectionView的工作流程
使用一个控件无非是获得数据,然后布局,最后显示;UICollectionView与UITableView类似是DataSource和Delegate驱动的。UICollectionView从数据源获取Cell,再从UICollectionViewLayout获取对应的layout attributes,最后根据layout attributes布局cell,显示界面。
2、视图
UICollectionView中有三种视图:Cell视图、Supplementary视图和Decoration视图
•Cells 用于展示内容的主体,对于不同的cell可以指定不同尺寸和不同的内容,这个稍后再说
•Supplementary Views 追加视图 如果你对UITableView比较熟悉的话,可以理解为每个Section的Header或者Footer,用来标记每个section的view
•Decoration Views 装饰视图 这是每个section的背景,比如iBooks中的书架就是这个
3、方法
(1)Data Source方法
—-section的数量—numberOfSectionsInCollection
—-某个section里有多少item—collectionView:numberOfItemsInSection:
—-对于某个位置应该显示什么样的cell—collectionView:cellForItemAtIndexPath
基本上上述三个方法就可以运作collectionView,但是还要提供Supplementary View方法
-collectionView:viewForSupplementaryElementOfKind:atIndexPath
对于Decoration Views,提供的方法在UICollectionViewLayout类中,因为它仅与视图有关。
(2)Delegate方法
Delegate方法负责view的外形、与用户交互,与数据无关。例如:cell的高亮、cell的选中状态以及长按后的菜单。
每个cell现在有独立的高亮事件和选中事件的delegate,状态控制要比以前灵活一些,对应的高亮和选中状态分别由highlighted和selected两个属性表示。当用户点击cell的时候,会按照下面的流程向delegate进行询问
a、-collectionView:shouldHighlightItemAtIndexPath:是否应该高亮?
b、-collectionView:didHighlightItemAtIndexPath:如果a返回yes,则高亮
c、-collectionView:shouldSelectItemAtIndexPath:无论a返回的结果如何,都询问是否可被选中
d、-collectionView:didUnhighlightItemAtIndexPath: 如果a回答为是,那么现在取消高亮
e、-collectionView:didSelectItemAtIndexPath: 如果c回答为是,那么选中cell
(3)属性与方法
//布局属性
@property (nonatomic, strong) UICollectionViewLayout *collectionViewLayout;
@property (nonatomic, weak, nullable) id delegate;
@property (nonatomic, weak, nullable) id dataSource;
@property (nonatomic, weak, nullable) id prefetchDataSource NS_AVAILABLE_IOS(10_0);
@property (nonatomic, getter=isPrefetchingEnabled) BOOL prefetchingEnabled NS_AVAILABLE_IOS(10_0);
@property (nonatomic, strong, nullable) UIView *backgroundView;
4、关于Cell
(1)Cell简介
因为UICollectionView所用来展示的对象相比UITableView来说要来得灵活,大部分情况下更偏向于图像而非文字,因此需求将会千奇百怪。因此SDK提供给我们的默认的UICollectionViewCell结构上相对比较简单,由下至上:
首先是cell本身作为容器view
然后是一个大小自动适应整个cell的backgroundView,用作cell的背景
在上一层是selectesBackgroundView,是cell被选中时的背景
最后是一个contentView,自定义内容应被加在view上
(2)重用
UICollectionView中,Cell、Supplementary View和DecorationView都可以被重用,对cell的重用延用UITableView的重用方案,如果我们使用-registerNib:forCellReuseIdentifer:方法为某种类型的cell注册过nib的话,就可以省略每次判断并初始化cell的代码,要是重用队列里没有可用的cell,runtime自动帮我们生成并初始化可用的cell
//每次判断并初始化cell的代码
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@”MY_CELL_ID”];
if (!cell) { //如果没有可重用的cell,那么生成一个
cell = [[UITableViewCell alloc] init];
}
//配置cell,blablabla
return cell
UICollectionView中Apple继承使用了这个特性,并且把其进行了一些扩展。使用以下方法进行注册:
•-registerClass:forCellWithReuseIdentifier:
•-registerClass:forSupplementaryViewOfKind:withReuseIdentifier:
•-registerNib:forCellWithReuseIdentifier:
•-registerNib:forSupplementaryViewOfKind:withReuseIdentifier:
相比UITableView有两个主要变化:一是加入了对某个Class的注册,这样即使不用提供nib而是用代码生成的view也可以被接受为cell了;二是不仅只是cell,Supplementary View也可以用注册的方法绑定初始化了。在对collection view的重用ID注册后,就可以像UITableView那样简单的写cell配置了:
- (UICollectionView*)collectionView:(UICollectionView*)cv cellForItemAtIndexPath:(NSIndexPath*)indexPath {
MyCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@”MY_CELL_ID”];
// Configure the cell’s content
cell.imageView.image = …
return cell;
}
5、UICollectionViewLayout
UICollectionViewLayout负责组织各个cell、Supplementary View和Decoration Views,为他们设定属性,例如设置下列属性:位置、尺寸、透明度、层级关系、形状等等。UICollectionViewLayout决定了UICollectionView如何显示在界面上,apple提供给我们一个最常用的默认的layout对象—UICollectionViewFlowLayout,开发者也可以根据自己的需要自定义UICollectionViewLayout赋予CollectionView的collectionViewLatout属性。
UICollectionViewFlowLayout。Flow Layout简单说是一个直线对齐的layout,最常见的Grid View形式即为一种Flow Layout配置。上面的照片架界面就是一个典型的Flow Layout。
(1)itemSize,它定义了每一个item的大小。通过设定itemSize可以全局地改变所有cell的尺寸,如果想要对某个cell制定尺寸,可以使用-collectionView:layout:sizeForItemAtIndexPath:方法。
(2)间隔 可以指定item之间的间隔和每一行之间的间隔,和size类似,有全局属性,也可以对每一个item和每一个section做出设定:
@property (CGSize) minimumInteritemSpacing
@property (CGSize) minimumLineSpacing
-collectionView:layout:minimumInteritemSpacingForSectionAtIndex:
-collectionView:layout:minimumLineSpacingForSectionAtIndex:
(3)滚动方向 由属性scrollDirection确定scroll view的方向,将影响Flow Layout的基本方向和由header及footer确定的section之间的宽度
UICollectionViewScrollDirectionVertical
UICollectionViewScrollDirectionHorizontal
(4)Header和Footer尺寸 同样地分为全局和部分。需要注意根据滚动方向不同,header和footer的高和宽中只有一个会起作用。垂直滚动时section间宽度为该尺寸的高,而水平滚动时为宽度起作用,如图。
@property (CGSize) headerReferenceSize
@property (CGSize) footerReferenceSize
-collectionView:layout:referenceSizeForHeaderInSection:
-collectionView:layout:referenceSizeForFooterInSection:
(5)缩进
@property UIEdgeInsets sectionInset;
-collectionView:layout:insetForSectionAtIndex:
总结
一个UICollectionView的实现包括两个必要部分:UICollectionViewDataSource和UICollectionViewLayout,和一个交互部分:UICollectionViewDelegate。而Apple给出的UICollectionViewFlowLayout已经是一个很强力的layout方案了。