CollectionView是iOS 6引入的控件,今天的重点并不是介绍它,而是使用它进行布局。效果图如下:
两列效果图.png
三列效果图.png
看了效果图,再来说说具体的实现步骤:
1.添加CollectionView控件
[
self.view addSubview:
self.myCollectionView];
2.加载数据(在[self addData]方法中进行数据的处理)
self.myCVLayout.dataArr = [
self addData];
3.对CollectionView进行配置(懒加载)[1]
_myCollectionView = [[
UICollectionView alloc]initWithFrame:
self.view.frame collectionViewLayout:
self.myCVLayout];
_myCollectionView
.backgroundColor = [
UIColor orangeColor];
[_myCollectionView registerNib:[
UINib nibWithNibName:
@"MyCollectionViewCell" bundle:
nil] forCellWithReuseIdentifier:CVCell];
_myCollectionView
.dataSource =
self;
4.对约束layout进行配置(懒加载)
_myCVLayout = [[CollectionLayout alloc]initOptionWithColumnNum:
2 rowSpacing:
10.0f columnSpacing:
10.0f sectionInset:UIEdgeInsetsMake(
20,
10,
10,
10)];
5.配置CollectionView的dataSource方法
- (
NSInteger)collectionView:(
UICollectionView *)collectionView numberOfItemsInSection:(
NSInteger)section {
return self.myCVLayout.dataArr.count;
}
- (__kindof
UICollectionViewCell *)collectionView:(
UICollectionView *)collectionView cellForItemAtIndexPath:(
NSIndexPath *)indexPath {
MyCollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:CVCell forIndexPath:indexPath];
cell
.image.image = [
UIImage imageNamed:
self.myCVLayout.dataArr[indexPath
.row]];
return cell;
}
6.创建一个UICollectionViewLayout的类,并结合第3步CollectionView的配置进行配置
if (
self = [
super init]) {
_columnNum = columnNum;
_rowSpacing = rowSpacing;
_columnSpacing = columnSpacing;
_sectionInset = sectionInset;
_everyColumnHDict = [
NSMutableDictionary dictionary];
_attributeArr = [
NSMutableArray array];
}
7.计算图片显示的高度
NSString * imageName = _dataArr[i];
UIImage * image = [
UIImage imageNamed:imageName];
CGFloat imageH = image
.size.height / image
.size.width * width;
return imageH;
8.重写prepareLayout方法[2]
for (
int i =
0; i < _columnNum; i++) {
[_everyColumnHDict setObject:@(_sectionInset
.top) forKey:[
NSString stringWithFormat:
@"%d",i]];
}
for (
int i =
0; i < _dataArr
.count; i++) {
[_attributeArr addObject:[
self layoutAttributesForItemAtIndexPath:[
NSIndexPath indexPathForItem:i inSection:
0]]];
}
9.重写layoutAttributesForItemAtIndexPath方法
UICollectionViewLayoutAttributes * attribute = [
UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
CGFloat itemW = (
self.collectionView.bounds.size.width - _sectionInset
.left - _sectionInset
.right - (_columnNum -
1) * _rowSpacing) / _columnNum;
CGFloat itemH = [
self calculateImageHeightWithCount:indexPath
.row withWidth:itemW];
CGRect frame =
CGRectMake(
0,
0, itemW, itemH);
NSInteger x =
0;
CGFloat y =
0.0f;
for (
id temKey
in _everyColumnHDict) {
CGFloat temHeight = [_everyColumnHDict[temKey] floatValue];
if (y ==
0) {
y = temHeight;
x = [temKey integerValue];
continue;
}
if(y > temHeight ) {
y = temHeight;
x = [temKey integerValue];
}
}
frame
.origin =
CGPointMake(_sectionInset
.left + x * (itemW + _rowSpacing), y);
NSString * key = [
NSString stringWithFormat:
@"%ld",x];
NSNumber * height = @(_columnSpacing + y + itemH);
[_everyColumnHDict setObject:height forKey:key];
attribute
.frame = frame;
return attribute;
10.重写collectionViewContentSize方法(设置可滚动的范围)
CGFloat height =
0.0f;
for (
id key
in _everyColumnHDict) {
CGFloat temHeight = [_everyColumnHDict[key] floatValue];
height = height > temHeight ? height : temHeight;
}
return CGSizeMake(
self.collectionView.frame.size.width, height + _sectionInset
.bottom);
11.重写layoutAttributesForElementsInRect方法
return _attributeArr;
注释写的非常清楚了,列数、边距之类的自己改下第4步的参数即可。有不明白的也可以看Demo,欢迎大家Star.
版权声明:本文为 Crazy Steven 原创出品,欢迎转载,转载时请注明出处!
[1]:需要注意第三句代码,UITableView可以自己创建新的cell,不一定非要注册,但CollectionView必须要注册才可使用。 ↩
[2]:_everyColumnHDict字典的key值代表第几列,value值代表这一列的高度,这里只是设置了初始值,无论第几列,第一行的高度都是_sectionInset.top;_attributeArr数组中保存的是每一个item的布局约束 ↩
文/CrazySteven(简书作者)
原文链接:http://www.jianshu.com/p/750ff6aa424d
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
转载请注明原文地址: https://ju.6miu.com/read-1300128.html