您的位置:首页 > 产品设计 > UI/UE

iOS开发之UICollectionView(二)

2016-01-11 15:02 441 查看
本文主要介绍自定义UICollectionView布局类UICollectionViewLayout,实现简单瀑布流视图。

利用自定义UICollectionViewLayout类实现瀑布流步骤:

新建继承自UICollectionViewLayout的类。
重写以下方法。

下面介绍一下需要在UICollectionViewLayout子类中需要重写的方法,如下:

重写prepareLayout函数:预加载布局函数

/**
*  重写预加载布局函数,只会被执行一次
*/
- (void)prepareLayout {

[super prepareLayout];

// 初始化必要数据
// 如:cell个数([self.collectionView numberOfSections]),cell宽度等

// 初始化必要数据
[self setupInitData];

// 计算宽度
[self setupCellWidth];

// 随机高度
[self setupCellHeight];

}

/**
*  生成cell的随机高度,模拟不等高现象
*/
- (void)setupCellHeight {

self.cellHeightArray = [[NSMutableArray alloc] initWithCapacity:self.numberCellsInSections];

for (int i = 0 ; i < self.numberCellsInSections; i ++) {

CGFloat cellHeight = arc4random() % (int)(self.cellMaxHeight - self.cellMinHeight) +
self.cellMinHeight;

[_cellHeightArray addObject:@(cellHeight)];

}

}

/**
*  计算cell的宽度
*/
- (void)setupCellWidth {

// 每列cell的宽度相同
self.cellWidth = (SCREEN_WIDTH - (HXColumnCount - 1) * HXCellsMargin) / HXColumnCount;

// 计算每个cell的x坐标
self.cellXArray = [[NSMutableArray alloc] initWithCapacity:HXColumnCount];

for (int i = 0 ; i < HXColumnCount; i ++) {
CGFloat tempX = i * (self.cellWidth + HXCellsMargin);

[self.cellXArray addObject:@(tempX)];
}

}

- (void)setupInitData {
self.numberOfSections = [self.collectionView numberOfSections];
self. numberCellsInSections = [self.collectionView numberOfItemsInSection:0];

// 约束自动生成的图片的高度在100-200之间
self.cellMinHeight = 100;
self.cellMaxHeight = 200;
}


重写collectionViewContentSize函数:设置滚动范围

/**
*  重设滚动范围
*/
- (CGSize)collectionViewContentSize {

CGFloat height = [self cellMaxYWithArray:self.cellYArray];

return CGSizeMake(SCREEN_WIDTH, height);

}

- (CGFloat)cellMaxYWithArray:(NSMutableArray *)array {

if (array.count == 0) {
return 0.0;
}

CGFloat cellMaxY = [array[0] floatValue];// 默认第一个最大
for (NSNumber *num in array) {

CGFloat tempY = [num floatValue];

if (tempY > cellMaxY) {
cellMaxY = tempY;
}
}

return cellMaxY;

}


重写layoutAttributesForElementsInRect:函数:给每个cell绑定一个layoutAttributes属性,并返回

/**
*  重写该方法,返回每个cell的layoutAttributes属性
*  给每个cell绑定一个layoutAttributes属性
*/
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {

[self initCellYArray];// 初始化存储每列cell的y值数组

NSMutableArray *array = [NSMutableArray array];

for (int i = 0; i < self.numberCellsInSections; i ++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];

UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];

[array addObject:attributes];
}
return array;
}

- (void)initCellYArray {

self.cellYArray = [[NSMutableArray alloc] initWithCapacity:HXColumnCount];

for (int i = 0; i < HXColumnCount; i ++) {
[self.cellYArray addObject:@(0)];
}

}


重写layoutAttributesForItemAtIndexPath:函数:制定每个cell的layoutAttributes属性

/**
*  指定每个cell的layoutAttributes属性
*/
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {

UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

CGRect frame = CGRectZero;

CGFloat cellHeight = [self.cellHeightArray[indexPath.row] floatValue];
int minYindex = [self cellMinYIndexWithArray:self.cellYArray];

CGFloat tempX = [self.cellXArray[minYindex] floatValue];
CGFloat tempY = [self.cellYArray[minYindex] floatValue];

frame = CGRectMake(tempX, tempY, self.cellWidth, cellHeight);

self.cellYArray[minYindex] = @(tempY + cellHeight + HXCellsMargin);

// 绑定
attributes.frame = frame;

return attributes;

}

- (int)cellMinYIndexWithArray:(NSMutableArray *)array {

if (array.count == 0) {
return 0.0;
}

// 默认最小Y值、以及最小Y值对应的索引
CGFloat min = [array[0] floatValue];
int minIndex = 0;

for (int i = 0 ; i < array.count; i ++) {

CGFloat temp = [array[i] floatValue];

if (temp < min) {
min = temp;
minIndex = i;
}
}

return minIndex;
}
自定义完UICollectionViewLayout子类后,在控制器中使用它,如下:

- (void)viewDidLoad {
[super viewDidLoad];
// 设置collectionView布局方式
<span style="color:#FF0000;">HXCollectionViewFallLayout</span> *fallLayout = [[<span style="color:#FF0000;">HXCollectionViewFallLayout</span> alloc] init];

// 创建collectionView
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:fallLayout];
// 设置collectionView背景颜色
collectionView.backgroundColor = [UIColor redColor];

// 设置数据源和代理
collectionView.dataSource = self;
collectionView.delegate = self;

// 注册一个collectionView Cell
[collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"COLLECTIONCELL"];

[self.view addSubview:collectionView];
self.collectionView = collectionView;

}
将UICollectionView的布局模式设置成自定义的布局即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: