UICollectionView

Posted Kingdev

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UICollectionView相关的知识,希望对你有一定的参考价值。

UICollectionView是Apple在ios6开始,提供给我们的一个强大的控件。最简单的UICollectionView就是GridView,标准的UICollectionView包含如下几个部分:

1 UICollectionReusableView<SupplementaryView>:可以指定section的Header或者Footer
2 UICollectionViewCell:用于展示内容的主体,对于不同的cell可以指定不同尺寸和不同的内容

再次说明,UICollectionView的用法绝不止简单的几种!

实现一个简单的UICollectionView

UICollectionView的实现和UITableView类似,都是数据源(datasource)和代理(delegate)设计模式。datasource:提供数据源,告诉UICollectionView需要显示什么东西;delegate:代理,用于实现和用户交互。

 1 /// 必须实现的数据源方法
 2 /** 
 3  返会cell的数量
 4  */
 5 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;
 6 
 7 /**
 8  返会cell视图
 9  */
10 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
11 
12 
13 /// 可选实现的数据源方法
14 /**
15  返会section的数量
16  */
17 - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;
18 
19 /** 
20  返回头部或尾部
21  */
22 - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
23 
24 /** 
25  iOS9系提供的方法,和cell的移动有关
26  */
27 - (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath;
28 - (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath;

为了更高效的使用cell,实现重用是必须的,值得注意的是,UICollectionViewCell使用之前必须先注册cell

 1 /**
 2  注册cell
 3  */
 4 - (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
 5 - (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;
 6 
 7 /** 
 8  注册头部尾部
 9  */
10 - (void)registerClass:(nullable Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;
11 - (void)registerNib:(nullable UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier;

对比于UITableViewCell的重用,苹果对UICollectionViewCell的重用做了优化,并未提供如下代码实现的方法:

1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
2     static NSString *reuseIdetifier = @"UITableViewCell";
3     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
4     if (!cell) {
5         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
6     }
7     return cell;
8 }

分析:UICollectionViewCell起初注册了cell,我们只需要在数据源方法里面书写如下代码即可,不需要每次都判断cell是否存在。要是在重用队列里没有可用的cell的话,runtime将自动帮我们生成并初始化一个可用的cell。

/**
  注册cell    
*/
[collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];

/**
  实现数据源方法
*/
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
    return cell;
}

 

UICollectionViewLayout,布局,之所以能实现各种效果,全依赖于这个类!UICollectionViewFlowLayout是苹果给我们实现好的一个类似流水布局的布局类。下面,来说明一下UICollectionViewFlowLayout的属性:

/** 
 每一行cell的最小间距
 */
@property (nonatomic) CGFloat minimumLineSpacing;

/**
 cell之间的最小间距
 */
@property (nonatomic) CGFloat minimumInteritemSpacing;

/**
 cell的尺寸(如果cell尺寸是固定的,直接指定该属性即可,不需要另外实现代理方法再去计算尺寸)
 */
@property (nonatomic) CGSize itemSize;

/**
 估算的cell尺寸
 */
@property (nonatomic) CGSize estimatedItemSize NS_AVAILABLE_IOS(8_0);

/**
 指定UICollectionView滚动方法
 */
@property (nonatomic) UICollectionViewScrollDirection scrollDirection;

/**
 头部尺寸
 */
@property (nonatomic) CGSize headerReferenceSize;

/**
 尾部尺寸
 */
@property (nonatomic) CGSize footerReferenceSize;

/**
 指定 UICollectionView 整体视图的上、左、下、右的缩进(间距)
 */
@property (nonatomic) UIEdgeInsets sectionInset;

/**
 iOS9新提供的,可以实现头部和尾部的悬浮效果
 */
@property (nonatomic) BOOL sectionHeadersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);
@property (nonatomic) BOOL sectionFootersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);

 

tip:当UICollectionView内容不足以占满整屏时会出现不能滑动的现场,以下为实现可滑动的方法:

    /// 建议只把和布局滚动方向一致的bounce设置为YES
    // 情况一
    flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
    collectionView.alwaysBounceVertical = YES;
    
    // 情况二
    flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    collectionView.alwaysBounceHorizontal = YES;

 

尊重作者劳动成果,转载请注明: 【kingdev】

以上是关于UICollectionView的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 未显示以查看

UICollectionView:ObjC Apple 示例代码到 Swift 转换(找不到成员)

如何从代码中选择 UICollectionView 的项目/单元格

在 UICollectionView 中自动调整单元格(全部在代码中)

Xcode8+Swift3 纯代码模式实现 UICollectionView

UICollectionView 在移动应用上创建新闻提要的代码