文章目录
UICollectionView与UITableView
UICollectionView是iOS6之后引入的一个新的UI控件,它和UITableView有着诸多相似之处,很多代理方法都十分类似,但UICollectionView是比UITableView更加强大的控件,有如下几个方面
- 支持水平和垂直两个方向上的布局
- 通过layout配置方式进行布局
- CollectionView中的item大小和位置可以自定义
- 通过layout布局回调的代理方法,可以动态的定制每一个item的大小和collection的大体布局属性
- 可以完全自定义一套layout布局方案,实现意想不到的效果
实现一个简单的九宫格类布局
#import "ViewController.h"
@interface ViewController () <UICollectionViewDelegate, UICollectionViewDataSource>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor grayColor];
//layout布局类
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
//布局方向为垂直流布局
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
//layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
//设置每个item的大小
layout.itemSize = CGSizeMake(120, 100);
_collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
//代理设置
_collectionView.delegate = self;
_collectionView.dataSource = self;
//注册item类型,这里使用系统类型
//必须注册!!!!,注册类似于tableView,但又不同于tableView,因为tableView有不注册的方法,临时创建
//iOS6之后的新类,统一从cell复用池获取cell,没有提供返回nil的方式
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
[self.view addSubview:_collectionView];
}
//返回分区个数
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
//返回每个分区的item个数
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 30;
}
//返回每个item
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
//只能用上面这个方法获取,其他方法都会崩溃
//UICollectionViewCell *cell = [[UICollectionViewCell alloc] init];
cell.backgroundColor = [UIColor colorWithRed:arc4random() % 255 / 255.0 green:arc4random() % 255 / 255.0 blue:arc4random() % 250 / 250.0 alpha:1];
return cell;
}
UICollectionView的代理方法
UICollectionViewDataSource协议
这个协议主要用于collectionView相关数据的处理
首先有两个方法是必须要实现的
- 设置每个分区的Item个数
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;
- 设置返回每个item的属性
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
下面的方法都是可选实现的
- 设置分区数,虽然这个方法是可选的,一般我们都会去实现
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;
- 对头视图或者尾视图进行设置
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
- 设置某个item是否可以被移动,返回NO则不能移动
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);
- 移动item的时候,会调用这个方法
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath;
UICollectionViewDelegate协议
这个协议用来设置和处理collectionView的功能和一些逻辑,所有的方法都是可选实现
- 是否允许某个Item的高亮,返回NO,则不能进入高亮状态
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
- 当item高亮时触发的方法
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
- 结束高亮状态时触发的方法
- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath
- 是否可以选中某个Item,返回NO,则不能选中
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath;
- 是否可以取消选中某个Item
- (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath;
- 已经选中某个item时触发的方法
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath;
- 取消选中某个Item时触发的方法
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath;
- 将要加载某个Item时调用的方法
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0);
- 将要加载头尾视图时调用的方法
- (void)collectionView:(UICollectionView *)collectionView willDisplaySupplementaryView:(UICollectionReusableView *)view forElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0);
- 已经展示某个Item时触发的方法
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath;
- 已经展示某个头尾视图时触发的方法
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingSupplementaryView:(UICollectionReusableView *)view forElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;
- collectionView进行重新布局时调用的方法
- (nonnull UICollectionViewTransitionLayout *)collectionView:(UICollectionView *)collectionView transitionLayoutForOldLayout:(UICollectionViewLayout *)fromLayout newLayout:(UICollectionViewLayout *)toLayout;
使用FlowLayout进行灵活布局
布局的管理类UICollectionViewFlowLayout
关于布局的相关设置和属性方法,通过对layout的设置,我们可以编写更加灵活的布局效果
前面的基础九宫格的布局方式中规中矩,有时候并不能满足我们的需求,有时我们需要对每一个item展示不同的大小
在上面那份代码中添加这个方法的实现
//设置每个item的大小,双数的为70*70 单数的为120*120
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *