在iOS开发中,与列表展示相关的,更多的是使用UITableView,几乎每个App都离不开它。对比与UITableView,UICollectionView的使用比较繁琐,所以UICollectionView的使用不是很常见。但UICollectionView也有自身的特点,比如横向布局,多行或者多列(瀑布流)展示。Apple也推荐了一些应用UICollectionView典型场景--相册、书库。
1.UICollectionView的创建
与UITableView类似,UICollectionView也可以通过控件的形式创建,其展示的UICollectionViewCell也可以是XIB的形式,这里更好的理解,使用代码创建。
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout
UICollectionView的创建过程基本和UITableView类似,alloc后init,设置dataSource代理和delegate代理,并添加到当前view上。不同于UITableView初始化时一般要指定UITableViewStyle,UICollectionView初始化时指定的是UICollectionViewLayout对象(一般都是使用它的子类UICollectionViewFlowLayout)。这个对象保存了关于UICollectionView的布局信息。其主要属性有
@property (nonatomic) CGFloat minimumLineSpacing;
@property (nonatomic) CGFloat minimumInteritemSpacing;
@property (nonatomic) CGSize itemSize;
@property (nonatomic) UICollectionViewScrollDirection scrollDirection; // default is UICollectionViewScrollDirection
@property (nonatomic) UIEdgeInsets sectionInset;
图为纵向滚动的UICollectionView
解释一下含义
scrollDirection 方向
默认纵向
itemSize 即一个Item的大小,蓝色线指示的大小
在UITableView中,Cell一般的宽度是屏幕的宽度,默认高度是44,我们常常是用heightForRowAtIndexPath来确定Cell的大小。
minimumLineSpacing 红色线之间的距离
//The minimum spacing to use between lines of items in the grid.
因为UICollectionView可以一行显示多个或者一列显示多个,这个属性用来指示行与行之间的最小距离(纵向),或者列与列之间的最小距离(横向)。无论横向或者纵向,都可以滚动显示所有内容,所以这个属性可以单独设置。
注意:这里定义UICollectionView的方向建立在设备在Portrait方向,即正常方向。如果考虑设备转换方向,那么UICollectionView的所有方向都可以看为是纵向。
minimumInteritemSpacing 黄色线之间的距离
//The minimum spacing to use between items in the same row.
用来指示同行(纵向)或者同列(横向)的item之间最小距离。在纵向滚动时,屏幕宽度固定,横向滚动时,屏幕的高度固定,故该属性的设置需要考虑itemSize。当设置过大时,布局就会与预期不一致。如在上图的情况下,如果该属性设置过大,导致一行无法放置2个Item,其结果就是每行只有一个Item。
sectionInset 每一个 section 与周边的间距
2.代理协议
代理协议有3个
UICollectionViewDelegateFlowLayout
UICollectionViewDelegate
UICollectionViewDataSource
UICollectionViewDelegateFlowLayout对应于UICollectionViewFlowLayout的属性设置,属性是全局一致的,如果需要特殊设置(瀑布流等),就可以使用协议的方式来对每个对象进行布局。主要方法如下
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
UICollectionViewDataSource协议与UITaleViewDataSource协议类似,常用协议如下
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;
分别对应Section多少个Item,展示的UICollectionViewCell和UICollectionView多少个Section。
CollectionView也使用了重用机制,可以
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
自行判断为空后再创建Cell,或者用
- (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
来注册Cell。
UICollectionViewDelegate协议与UITaleViewDelegate协议类似,常用协议如下
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath;
分别对应Item的选中和取消选中操作。