文章目录
前言
UICollectionView 是一个强大的 UIKit 组件,用于展示数据集合,比如图片、文字列表等。它支持复杂的布局,包括网格、瀑布流等。以下是我个人在学习UICollectionView时的笔记。
UICollectionView
什么是UICollectionView
UICollectionView 是一个高度可定制的视图,可以展示一个或多个子视图(UICollectionViewCell),这些子视图可以被组织成不同的布局。它常用于展示图片、列表、网格等,并且支持用户交互,如滚动、选择和拖拽。
UICollectionView的关键特性
布局灵活性:UICollectionView 的布局由 UICollectionViewLayout 及其子类负责。我们可以通过使用不同的 UICollectionViewLayout 子类,如 UICollectionViewFlowLayout(用于线性布局,可以是水平或垂直滚动),来创建各种布局。苹果提供了一个默认的布局类 UICollectionViewFlowLayout,它支持流式布局(如网格和列表)。你可以通过继承 UICollectionViewLayout 来创建自定义布局,以实现更复杂的布局效果。
重用机制:为了提高性能,UICollectionView 重用单元格(cell)和视图(如头视图和尾视图),这有助于在滚动时管理内存使用。
数据源和代理:UICollectionView 通过数据源(UICollectionViewDataSource)和代理(UICollectionViewDelegate)与数据模型交互,处理数据的显示和用户交互。
选择和高亮:通过代理方法,可以处理用户的选中和取消选中操作,以及单元格的高亮显示。
拖拽和重新排序:UICollectionView 支持拖拽操作,允许用户重新排序单元格。
自定义绘制:我们可以自定义 UICollectionViewCell 的内容,包括布局、视图和动画效果。
UICollectionView组成及常用方法
组成
UICollectionViewFlowLayout:这是一个 UICollectionViewLayout 的子类,提供了线性布局(行和列)。它允许你定义项目的尺寸、行间距、列间距、分区的边距等。
UICollectionViewCell:这是 UICollectionView 中的单个项目,类似于 UITableView 中的 cell。你可以自定义这个 cell 来展示你的数据。
UICollectionReusableView:这是用于创建分区头(section headers)和分区尾(section footers),以及其他补充视图。
DataSource:定义了 collection view 中的数据,必须实现 UICollectionViewDataSource 协议。
Delegate:处理用户的交互,比如选中项目,必须实现 UICollectionViewDelegate 协议。
常用方法
UICollectionView 继承于 UIScrollView,UICollectionViewDelegate 协议继承于 UIScrollViewDelegate 协议。所以在使用 UICollectionView 的时候,可以直接使用 UIScrollView 的各个属性方法。
UIScrollView 中有几个重要的属性,contentSize用来标识 UIScrollView 的滚动范围;contentOffset 用来设置视图原点与可视区域左上角的距离;contentInset 可用通过 UIEdgeInsetMake(10,10,10,10) 的方法设置一个内边框,这个值可以是负的,能使视图超出可视的滚动范围。
我们可以通过 setContentOffset:animated: 将视图滚动到某一个位置,也可以使用 scrollRectToVisible:animated: 将某块 rect 滚动到可视区域内(如果已经可见则不会滚动)。
UICollectionViewDataSource 协议方法(这些方法必须实现,以便提供 collection view 的数据):
objectivec
numberOfSectionsInCollectionView://返回 collection view 中的分区数量。
collectionView:numberOfItemsInSection://返回指定分区中的项目数量。
collectionView:cellForItemAtIndexPath://为指定的 indexPath 配置并返回一个 cell。
collectionView:viewForSupplementaryElementOfKind:atIndexPath//为指定的分区和补充元素(如分区头或尾)配置并返回一个补充视图。
UICollectionViewDelegate 协议方法(这些方法用于处理用户的交互和自定义 collection view 的行为):
objectivec
collectionView:didSelectItemAtIndexPath://当用户选中一个项目时调用。
collectionView:didDeselectItemAtIndexPath://当用户取消选中一个项目时调用(如果允许多选)。
collectionView:willDisplayCell:forItemAtIndexPath://在 cell 即将显示在屏幕上时调用。
collectionView:didEndDisplayingCell:forItemAtIndexPath://当 cell 从屏幕上消失时调用。
UICollectionView 布局方法(这些方法与布局相关,通常在自定义 UICollectionViewLayout 时使用):
objectivec
collectionView:layout:sizeForItemAtIndexPath:
//返回指定项目的大小。
collectionView:layout:insetForSectionAtIndex:
//返回指定分区的内边距。
collectionView:layout:minimumLineSpacingForSectionAtIndex:
//返回指定分区的行间距。
collectionView:layout:minimumInteritemSpacingForSectionAtIndex:
//返回指定分区的列间距。
collectionView:layout:referenceSizeForHeaderInSection:
//返回分区头的大小。
collectionView:layout:referenceSizeForFooterInSection:
//返回分区尾的大小。
UICollectionView 自定义方法:
objectivec
registerClass:forCellWithReuseIdentifier:
//注册一个 cell 类和其重用标识符。
registerNib:forCellWithReuseIdentifier:
//注册一个 cell 的 nib 文件和其重用标识符。
registerClass:forSupplementaryViewOfKind:withReuseIdentifier:
//注册一个补充视图类和其重用标识符。
registerNib:forSupplementaryViewOfKind:withReuseIdentifier:
//注册一个补充视图的 nib 文件和其重用标识符。
dequeueReusableCellWithReuseIdentifier:forIndexPath:
//重用或创建一个 cell。
dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
//重用或创建一个补充视图。
UICollectionView 更新和动画方法:
objectivec
reloadData//重新加载 collection view 的所有数据。
performBatchUpdates:completion://执行一系列的更新操作,并提供动画。
insertSections://插入分区。
deleteSections://删除分区。
reloadSections://重新加载分区。
insertItemsAtIndexPaths://插入项目。
deleteItemsAtIndexPaths://删除项目。
reloadItemsAtIndexPaths://重新加载项目。
moveItemAtIndexPath:toIndexPath://移动项目。
UiCollectionView的基本使用及代码示例
- 定义 UICollectionView 和 UICollectionViewLayout
objectivec
// 创建 layout
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(80, 80); // 设置每个 item 的大小
layout.minimumLineSpacing = 10; // 设置行间距
layout.minimumInteritemSpacing = 10; // 设置列间距
layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10); // 设置分区边距
// 创建 collection view
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
collectionView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:collectionView];
// 设置 dataSource 和 delegate
collectionView.dataSource = self;
collectionView.delegate = self;
- 注册 Cell 和 Supplementary Views
objectivec
// 注册 cell
[collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
// 注册分区头
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"Header"];
- 实现 DataSource 方法
objectivec
// 返回分区数量
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1; // 一个分区
}
// 返回每个分区中的项目数量
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 25; // 这个分区有 25 个项目
}
// 配置并返回 cell
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
// 配置 cell
cell.backgroundColor = [UIColor redColor];
return cell;
}
- 实现 Delegate 方法(可选)
objectivec
// 选中项目
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"选中了项目 %ld", (long)indexPath.item);
}
- 配置 Supplementary Views
objectivec
// 添加分区头
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
UICollectionReusableView *header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"Header" forIndexPath:indexPath];
header.backgroundColor = [UIColor blueColor];
return header;
}
总结
关于UICollectionView的基本用法,我暂时学到这里,还有更深层次的大家可以看看这篇参考文章,这篇文章讲的非常详细,具体的用法还需在后续学习中多多体悟。