1、实现UICollectionView最重要的就是计算UICollectionViewFlowLayout,因为UICollectionView的每个cell的位置都是根据这个layout决定的
下面贴上主要代码:
#import "ViewController.h"
#import "PicModel.h"
#import "PicFlowLayout.h"
#import "PicCollectionViewCell.h"
@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate>
{
NSMutableArray * _dataArray;
UICollectionView * _collectionView;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor whiteColor];
CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;
_dataArray = [[NSMutableArray alloc] init];
for (int i = 1; i <= 28; i++) {
NSString * picPathStr = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"pic%i", i] ofType:@"jpg"];
NSData * picData = [NSData dataWithContentsOfFile:picPathStr];
UIImage * image = [UIImage imageWithData:picData];
PicModel * model = [[PicModel alloc] init];
model.image = image;
model.imageHeight = image.size.height;
model.imageWidth = image.size.width;
model.width = screenWidth/2;
model.height = model.imageHeight * (model.width/model.imageWidth);
[_dataArray addObject:model];
}
PicFlowLayout * layout = [[PicFlowLayout alloc] init];
layout.dataArray = _dataArray;
//collectionView的每个cell根据对应的layout进行布局
_collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
_collectionView.dataSource = self;
_collectionView.delegate = self;
[self.view addSubview:_collectionView];
[_collectionView registerClass:[PicCollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
_collectionView.backgroundColor = [UIColor whiteColor];
}
#pragma mark --
#pragma mark UICollectionViewDataSource
//返回每个section的cell个数
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return _dataArray.count;
}
//返回cell
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
PicCollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
PicModel * model = _dataArray[indexPath.row];
[cell setModel:model];
return cell;
}
//
// PicFlowLayout.m
// 001-uicollectionview
//
// Created by zhonghj on 16/1/18.
// Copyright © 2016年 dzkj. All rights reserved.
//
#import "PicFlowLayout.h"
@implementation PicFlowLayout
//指定当前的collectionView的contentSize
- (CGSize)collectionViewContentSize
{
CGFloat leftHeight = 0.0f;//左边的总高度
CGFloat rightHeight = 0.0f;//右边的总高度
for (int i = 0; i < _dataArray.count; i++) {
PicModel * model = _dataArray[i];
if (leftHeight <= rightHeight) { //放左侧
leftHeight += model.height;
}else{
rightHeight += model.height;
}
}
return CGSizeMake(0, leftHeight > rightHeight?leftHeight: rightHeight);
}
//返回indexPath所对应的cell的属性
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes * attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;
PicModel * model = _dataArray[indexPath.row];
CGFloat leftHeight = 0.0f;//左边的总高度
CGFloat rightHeight = 0.0f;//右边的总高度
for (int i = 0; i < indexPath.row; i++) {
PicModel * subModel = _dataArray[i];
if (leftHeight <= rightHeight) { //放左侧
leftHeight += subModel.height;
}else{
rightHeight += subModel.height;
}
}
if (leftHeight <= rightHeight) { //放左侧
attr.center = CGPointMake(screenWidth/4, leftHeight + model.height/2);
}else{
attr.center = CGPointMake(screenWidth/4 * 3, rightHeight + model.height/2);
}
attr.size = CGSizeMake(screenWidth/2, model.height);
return attr;
}
//返回的数组,每一个元素和与之序号对应的cell的属性
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray * arr = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.collectionView numberOfItemsInSection:0]; i++) {
NSIndexPath * indexPath = [NSIndexPath indexPathForItem:i inSection:0];
UICollectionViewLayoutAttributes * attr = [self layoutAttributesForItemAtIndexPath:indexPath];
[arr addObject:attr];
}
return arr;
}
@end
程序截图:
初始:
拉到最下面:
附:本程序代码:https://github.com/dzonel/collectionView