UICollectionView的使用

实现垂直方向的单列表,使用UITableView;若是需要构建横向滑动列表、多行多列布局,使用UICollectionView+UICollectionViewFlowLayout搭建;更复杂的布局,则可以使用UICollectionView+自定义Layout来实现。

UICollectionView工作流程:

当UICollectionView显示内容时,先从数据源获取cell交给UICollectionView。再从UICollectionViewLayout获取对应的layout attributes(布局属性)。最后,根据每个cell对应的layout attributes(布局属性)来对cell进行布局,生成最终的界面。而用户交互的时候,都是通过Delegate来进行交互。当然,上面只是布局cell,但是UICollectionView内部还有Supplementary View和Decoration View,也可以对其进行布局。

一、视图

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。

在数据源方法当中返回cell或者Supplementary view的方法当中通过dequeueReusableCellWithReuseIdentifier:forIndexPath: 

或dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:方法获取cell或者Supplementary View。

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,显示编辑菜单 与UITableView不同,用户长按cell时,UICollectionView可以显示编辑菜单。这个编辑菜单可以用来剪切、复制和粘贴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是通过UICollectionViewLayoutAttributes类来管理cell、Supplementary View和Decoration View的位置、transform、alpha、hidden等等。 

UICollectionViewLayout这个类只是一个基类,我们给UICollectionView使用的都是它的子类。系统为我们提供了一个最常用的layout为UICollectionViewFlowLayout,我们可以使用它制作grid view。当UICollectionViewLayout满足不了我们的需求时,我们可以子类化UICollectionViewLayout或者自定义layout。

UICollectionViewFlowLayout内部常用的属性:

//同一组当中,垂直方向:行与行之间的间距;水平方向:列与列之间的间距
@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代理方法,进行对应的设置。

@protocol UICollectionViewDelegateFlowLayout <UICollectionViewDelegate>
//每个cell的尺寸
- (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; 
//垂直方向:同一行中cell之间的间距;水平方向:同一列中cell的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section; 
//每一组头视图的尺寸。如果是垂直方向滑动,则只有高起作用;如果是水平方向滑动,则只有宽起作用。
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section; 
//每一组尾部视图的尺寸。如果是垂直方向滑动,则只有高起作用;如果是水平方向滑动,则只有宽起作用
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;

 

posted @ 2017-04-05 17:20  笑薇薇smile  阅读(213)  评论(0编辑  收藏  举报