1.概述
UICollectionView是以列表形式展示数据的方式之一,他是继承自UIScrollView,可以上下(或者左右)滑动的视图。UIColectionView,通过自定义UICollectionViewLayout,有灵活的布局方式,例如瀑布流等。
2.初始化
需要用 UICollectionViewLayout初始化 UICollectionView,他定义UICollectionView的布局样式,这里使用的UICollectionViewFlowLayout是ios api中原有的,可以实现一个网格布局样式,也可以自己写一个集成UICollectionViewLayout的类,做自己需要的布局样式。
//排列样式
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
_collectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen]
.bounds collectionViewLayout:flowLayout];
注册UICollectionVIew的cell,MyCollectionCellCollectionViewCell为随意写的,但是必须继承UICollectionViewCell,现在这里其中只有一个UILabel。最后一个参数是该UICollectionView对应cell的唯一标识,如果有多个UICollectionView,注意不要相同。
//注册单元格
[_collectionView registerClass:[MyCollectionCellCollectionViewCell class]
forCellWithReuseIdentifier:@"cell"];
3.协议
使用UICollectionView需要实现如下两个协议,分别代表对他的数据提供和控制回调
UICollectionViewDataSource,UICollectionViewDelegate
以下为ViewController中加载UICollectionView。一般需要将自己作为协议实现对象
//数据源和代理
_collectionView.delegate = self;
_collectionView.dataSource = self;
4.数据协议的函数
数据源协议 UICollectionViewDataSource,设置UICollectionView展示的数据。
UICollectionView设置每个secion中的cell个数,要求必须实现
//每组单元格数量
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section {
return 12;
}
UICollectionView设置或者修改复用的cell,要求必须实现。dequeueReusableCellWithReuseIdentifier:forIndexPath:函数为系统函数,可以实现对已有的已经足够了的cell的复用,注意这里的唯一标识@"cell"需要与前文,collectionView的注册标志一致。
//生成和修改单元格
- (UIView *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyCollectionCellCollectionViewCell *cell = [collectionView
dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
if (!cell) {
cell = [[MyCollectionCellCollectionViewCell alloc] init];
}
cell.label.text = [NSString stringWithFormat:@"%zd", indexPath.row];
return cell;
}
UICollectionView设置有多少个区域,非必须,不实现,则默认为1
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 2;
}
UICollectionView定义每个cell 的长和宽,非必须实现。
- (CGSize)collectionView:(UICollectionView *)collectionView layout:
(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:
(NSIndexPath *)indexPath {
return CGSizeMake(WIDTH, WIDTH);
}
UICollectionView设置cell之间的水平间距 (同一行的cell的左右间距),非必须实现。
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:
(UICollectionViewLayout *)collectionViewLayout
minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 0;
}
UICollectionView的cell垂直间距 (同一列cell上下间距),非必须实现。
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:
(UICollectionViewLayout *)collectionViewLayout
minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 0;
}
UICollectionView 定义每个section 的边距,非必须。
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:
(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:
(NSInteger)section {
return UIEdgeInsetsMake(0, 0, 0, 0);
}
5.事件监听回调函数
UICollectionViewDelegate代理协议,主要是完成用户的控制回调,都是非必须实现的函数。
UICollectionView 选中某个cell。当用户点击某个cell,即选中这个cell,即进行此回调。
- (void)collectionView:(UICollectionView *)collectionView
didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"选中%zd",indexPath.row);
}
UICollectionView 取消选中某个cell。例如用户先点击1 再点击2,那么会先后经历:选中1->取消选中1->选中2
//取消选中
- (void)collectionView:(UICollectionView *)collectionView
didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"取消选中%zd",indexPath.row);
}
6.添加区域的头部
可以为UICollectionView添加每个section的头部。头部需要单独注册,同样注意Identifier的唯一性。
[_collectionView registerClass:[MySectionHeader class]
forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:@"header"];
UICollectionView 设置section的头部的宽高
- (CGSize)collectionView:(UICollectionView *)collectionView layout:
(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:
(NSInteger)section {
CGSize size = CGSizeMake(WIDTH * 3, 35);
return size;
}
UICollectionView 设置section的头部的view。MySectionHeader 为继承自UICollectionReusableView的一个自定义类,只有一个UILabel在其中,
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSString *)kind
atIndexPath:(NSIndexPath *)indexPath {
MySectionHeader *reusableView = nil;
if (kind == UICollectionElementKindSectionHeader) {
reusableView = (MySectionHeader *) [collectionView
dequeueReusableSupplementaryViewOfKind:
UICollectionElementKindSectionHeader withReuseIdentifier:@"header"
forIndexPath:indexPath];
if (indexPath.section == 0) {
reusableView.label.text = @"我是标题1";
} else {
reusableView.label.text = @"我是标题2";
}
}
return reusableView;
}