- 三个代理
<UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout>
前两个的用法和tableView的很像,第三个是布局的协议。(注意:头视图尾视图都是由代理方法获得,而且需要写注册,缺少了也不行。) 注册以后,就不需要再去管理复用的问题了。这点就很简单。这个如果用好的话,会非常的简单。
- item(即cell)的布局原理(类似tableView)
- header/footer View的布局原理
都是继承于UICollectionReusableView,并且必须要从dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:这个代理方法中获取,而且根据不同的kind作为headerView或者footerView,切记:collectionView中头部视图和尾部视图也需要注册
下面直接上代码,看注释即可:
ViewController.h
#import <UIKit/UIKit.h> @interface ViewController : UIViewController<UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>{ } @property (strong, nonatomic)UICollectionView *collectionView; @end
ViewController.m
#import "ViewController.h" #import "NewSceneCollectionHeaderView.h" #import "NewSceneCollectionFooterView.h" #import "NewSceneCollectionViewCell.h" @interface ViewController () @end //cell、header、footerView 标识 static NSString *cellIdentifier = @"NewSceneCollectionViewCell"; static NSString *headerIdentifier = @"NewSceneCollectionHeaderView"; static NSString *footerIdentifier = @"NewSceneCollectionFooterView"; @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //创建布局对象 UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; //flowlaout的属性,确定是水平滚动,还是垂直滚动 flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; //接下来就在创建collectionView的时候初始化,就很方便了(能直接带上layout) self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 200, 320, 280) collectionViewLayout:flowLayout]; self.collectionView.backgroundColor = [UIColor grayColor]; //指定数据源和代理 self.collectionView.delegate = self; self.collectionView.dataSource = self; //添加到主页面上去 [self.view addSubview:self.collectionView]; //collectionCell的注册 [self.collectionView registerClass:[NewSceneCollectionViewCell class] forCellWithReuseIdentifier:cellIdentifier]; //collection头视图的注册。 注意:奇葩的地方来了,头视图和尾部视图也得注册 [self.collectionView registerClass:[NewSceneCollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerIdentifier]; [self.collectionView registerClass:[NewSceneCollectionFooterView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:footerIdentifier]; /*另一种方式 //从Xib上注册 UINib *nib = nil; nib = [UINib nibWithNibName:cellIdentifier bundle:nil]; [self.collectionView registerNib:nib forCellWithReuseIdentifier:cellIdentifier]; //注册headerview和footerview nib = [UINib nibWithNibName:headerIdentifier bundle:nil]; [self.collectionView registerNib:nib forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerIdentifier]; nib = [UINib nibWithNibName:footerIdentifier bundle:nil]; [self.collectionView registerNib:nib forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:footerIdentifier]; */ [self.view addSubview:self.collectionView]; } /******************************************************** *UICollectionViewDataSource/Delegate/DelegateFlowLayout ********************************************************/ #pragma mark UICollectionViewDataSource/Delegate //返回多少组(section),此方法不写默认是1组(跟tableview类似) - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 2; } #pragma mark required //每组返回多少个Item,这个Item类似tableview中的cell - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return 10; } //返回cell,这里构建Item(即cell) - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { //这里是自定义的cell NewSceneCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; cell.backgroundColor = [UIColor redColor]; return cell; } #pragma mark optional //自定义header/footerView // The view that is returned must be retrieved from a call to -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath: //这里返回的view必须要从dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:这个方法中获取,而且根据不同的kind作为headerView或者footerView,切记:collectionView中头部视图和尾部视图也需要注册 - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { UICollectionReusableView *reusableView = nil; if (UICollectionElementKindSectionHeader == kind) { //这里是自定义的头视图 NewSceneCollectionHeaderView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:headerIdentifier forIndexPath:indexPath]; headerView.backgroundColor = [UIColor whiteColor]; return headerView; } if (UICollectionElementKindSectionFooter == kind { //这里是自定义的尾视图 NewSceneCollectionFooterView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:footerIdentifier forIndexPath:indexPath]; footerView.backgroundColor = [UIColor whiteColor]; return footerView; } return reusableView; } #pragma mark --UICollectionViewDelegateFlowLayout //布局确定每个Item 的大小 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { return CGSizeMake(100, 100); } //布局确定每个section内的Item距离section四周的间距 UIEdgeInsets -(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { return UIEdgeInsetsMake(10, 10, 10, 10); } //返回每个section内上下两个Item之间的间距 - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section { return 10; } //返回每个section内左右两个Item之间的间距 - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section { return 10; } //返回headerView的尺寸 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section { CGFloat width = CGRectGetWidth(collectionView.bounds); CGFloat height = width + 86; return CGSizeMake(width, height); } //返回footerView的尺寸 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section { CGFloat width = CGRectGetWidth(collectionView.bounds); CGFloat height = 144; return CGSizeMake(width, height); } #pragma mark --UICollectionViewDelegate //UICollectionView被选中时调用的方法 -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { NewSceneCollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; cell.backgroundColor = [UIColor greenColor]; NSLog(@"item======%ld",(long)indexPath.item); NSLog(@"row=======%ld",(long)indexPath.row); NSLog(@"section===%ld",(long)indexPath.section); } //返回这个UICollectionView是否可以被选择 -(BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath { return YES; }