文章目录
简介
CollectionView比tableView多了一个布局的东西,叫Collection View layout,集合视图的cell的位置上可以千变万化的,不像tableView就是一行一行的,
集合视图由三部分组成
cell:单元格
Supplementary View:补充视图,指的是Header和Footer
Decoration View:装饰视图,一般用于背景。
集合视图中的UICollectionViewLayout属性决定了Cell的布局方式,提供了两种布局:
- UICollectionViewFlowLayout:Flow Layout是一个Cells的线性布局方案,并具有页面和页脚。(常用),线性布局是从按照顺序,从左到右排满后后换行,从左到右。
- 自定义布局方式,需要创建一个新的UICollectionViewLayout自定义的类。
数据源协议dataSource
CollectionView的数据源协议为集合视图的Cell提供了数据来源,其基本和tableView的数据源方法类似,但区别在于集合视图需要提前注册cell。
1.注册cell
- (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;
2.实现3个数据源方法
//有多少个段
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView; - //指定每个在每个section里有几个item
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;
//设置每一个cell的样式
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
自定义CollectionView,推荐用xib的方式创建cell,记得关联类
MyCollectionViewController创建好后,自动有一些代码生成,需要根据自己的情况修改下。
//
// MyCollectionViewController.m
// CollectionViewDemo
//
// Created by 谢鑫 on 2019/7/7.
// Copyright © 2019 Shae. All rights reserved.
//
#import "MyCollectionViewController.h"
#import "MyCollectionViewCell.h"
@interface MyCollectionViewController ()
@end
@implementation MyCollectionViewController
static NSString * const reuseIdentifier = @"MyCell";
- (void)viewDidLoad {
[super viewDidLoad];
[self.collectionView registerNib:[UINib nibWithNibName:@"MyCollectionViewCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:reuseIdentifier];
}
#pragma mark <UICollectionViewDataSource>
//有多少个段
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 2;
}
//指定每个在每个section里有几个item
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 40;
}
//设置每一个cell的样式
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyCollectionViewCell *cell = (MyCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
cell.backgroundColor=[UIColor redColor];
return cell;
}
代理协议:点击cell
在tableView里面也是可以通过代理方法来监控cell的点击的。
一般来说开发中。点击cell都是打开一个新的控制器,通过导航控制器去push一个新的控制器。
#pragma mark <UICollectionViewDelegate>
//选中item
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
//获取点击的单元格
MyCollectionViewCell *cell=(MyCollectionViewCell*)[self.collectionView cellForItemAtIndexPath:indexPath];
cell.backgroundColor=[UIColor redColor];
}
//取消选中item
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{
//获取点击的单元格
MyCollectionViewCell *cell=(MyCollectionViewCell*)[self.collectionView cellForItemAtIndexPath:indexPath];
cell.backgroundColor=[UIColor blueColor];
}
选中的cell是红色,当选中其他cell时,之前选中的cell就变成蓝色了
实现多选:
self.collectionView.allowsMultipleSelection=YES;
对于多选的时候,当再次点击选中过的cell,就相当于进入取消选中状态了。
自定义Cell
tableView的cell默认情况时含有几个元素的,比如图片,title等。但集合视图就没有默认的元素,所以集合视图的cell都是需要定制的。
xib里要用自动布局的方式让视图自动去识别大小。
在cell的xib里拖入控件并设置布局,然后推动到cell的.h文件里添加属性,就可以在用到cell的时候对cell属性进行设置了。
indexPath.section
indexPath.row
形状设置
必须要遵守协议:继承自UICollectionViewController的类就不需要指定代理对象了。
@interface MyCollectionViewController ()<UICollectionViewDelegateFlowLayout>
#define kMargin 10
#pragma mark 形状设置
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
//获取屏幕大小
CGFloat screenWidth=[UIScreen mainScreen].bounds.size.width;
//计算cell的宽度
CGFloat cellWidth=(screenWidth-3*kMargin)*0.5;
return CGSizeMake(cellWidth, cellWidth);
}
//整体边距
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(kMargin, kMargin, kMargin, kMargin);
}
//cell之间的横向间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
return kMargin;
}
补充视图(Header和Footer)
1.创建自定义Header/Footer类(XIB方式)
- 创建一个自定义类,继承自:UICollectionReusableView
- 创建一个xib文件,并添加一个:Collection Reusable View 控件
- 定义样式
2.注册Header和Footer
- 分别添加Header和Footer的可重用标示符
static NSString *const reuseIdentifierHeader=@"MyHeaderCell";
static NSString *const reuseIdentifierFooter=@"MyFooterCell";
- 在viewDidLoad方法中注册Header和Footer
[self.collectionView registerNib:[UINib nibWithNibName:@"MyHeader" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:reuseIdentifierHeader];
[self.collectionView registerNib:[UINib nibWithNibName:@"MyFooter" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:reuseIdentifierFooter];
3.实现Header和Footer的数据源方法
实现CollectionView的viewForSupplementaryElementOfKind:代理方法,并设置Header和Footer的一些属性。函数里有一个kind参数,区别是Header还是Footer的参数。
# pragma mark -补充视图数据源方法-
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
UICollectionReusableView *supplementaryView;
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
//设置Header的属性
//缓存池中获取Header
MyHeader *view=[collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:reuseIdentifierHeader forIndexPath:indexPath];
view.headerLabel.text=[NSString stringWithFormat:@"Header:%ld",(long)indexPath.section];
supplementaryView=view;
}else if([kind isEqualToString:UICollectionElementKindSectionFooter]) {
//设置Footer的属性
MyFooter *view=[collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:reuseIdentifierFooter forIndexPath:indexPath];
view.footerLabel.text=[NSString stringWithFormat:@"Footer:%ld",(long)indexPath.section];
supplementaryView=view;
}
return supplementaryView;
}
4.设置Header与Footer的大小
实现UICollectionViewDelegateFlowLayout协议中的referenceSizeForHeaderInSection以及referenceSizeForFooterInSection方法,设置Header和Footer的大小。
必须要遵守协议:
@interface MyCollectionViewController ()<UICollectionViewDelegateFlowLayout>
就不需要指明代理对象了。
//必须设置Header和Footer的高度
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
//获取屏幕宽度
CGFloat screenWidth=[UIScreen mainScreen].bounds.size.width;
return CGSizeMake(screenWidth, 50);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{
CGFloat screenWidth=[UIScreen mainScreen].bounds.size.width;
return CGSizeMake(screenWidth, 50);
}
xib一定要设置类:
代码:https://github.com/ShaeZhuJiu/ios-CollectionViewController_base.git