注:其他属性值的获取与上述方法几乎完全相同,不再赘述
设置布局
1)、设置需要的成员属性
/**所有cell的布局属性*/
@property (nonatomic, strong) NSMutableArray *attrsArray;
/**所有列的当前高度*/
@property (nonatomic, strong) NSMutableArray *columnHeights;
2)、通过懒加载的方式初始化成员属性
/**--attrsArray--懒加载*/
- (NSMutableArray *)attrsArray
{
if (_attrsArray == nil)
{
_attrsArray = [NSMutableArray array];
}
return _attrsArray;
}
/**--columnHeights--懒加载*/
- (NSMutableArray *)columnHeights
{
if (_columnHeights == nil)
{
_columnHeights = [NSMutableArray array];
}
return _columnHeights;
}
3)、初始化布局
- (void)prepareLayout
{
[super prepareLayout];
/**清除之前跟布局相关的所有属性,重新设置新的布局*/
//清除之前计算的所有列的高度
[self.columnHeights removeAllObjects];
//设置所有列的初始高度
for (NSInteger i = 0; i<self.columnCount; i++)
{
self.columnHeights[i] = @(self.edgeInsets.top);
}
//清除之前所有的布局属性
[self.attrsArray removeAllObjects];
/**开始创建每一个cell对应的布局属性*/
NSInteger count = [self.collectionView numberOfItemsInSection:0];
for (NSInteger i = 0; i<count; i++)
{
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
//获取indexPath位置cell对应的布局属性
UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
//将indexPath位置的cell的布局属性添加到所有cell的布局属性数组中
[self.attrsArray addObject:attrs];
}
}
4)、返回包含所有cell的布局属性的数组
- (nullable NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
return self.attrsArray;
}
设置每一个cell的布局属性
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
{
//获取indexPath位置的布局属性
UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
/**设置cell布局属性的frame*/
/***确定cell的尺寸***/
//获取collectionView的宽度
CGFloat collectionViewWidth = self.collectionView.frame.size.width;
//cell宽度
CGFloat width = ((collectionViewWidth - self.edgeInsets.left - self.edgeInsets.right - (self.columnCount - 1) * self.columMargin)) / self.columnCount;
//cell高度
CGFloat height = [self.delegate waterFlowLayout:self heightForItemAtIndex:indexPath.item itemWith:width];
/***设置cell的位置***/
NSInteger destColumn = 0;
CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];
for (NSInteger i = 1; i<self.columnCount; i++)
{
CGFloat columnHeight = [self.columnHeights[i] doubleValue];
if (minColumnHeight > columnHeight)
{
minColumnHeight = columnHeight;
destColumn = i;
}
}
//计算cell的位置
CGFloat x = self.edgeInsets.left + destColumn * (width + self.columMargin);
CGFloat y = minColumnHeight;
//判断是不是第一行
if (y != self.edgeInsets.top)
{
//若不是第一行,需要加上行间距
y += self.rowMargin;
}
/**给cell的布局属性的frame赋值*/
attrs.frame = CGRectMake(x, y, width, height);
//更新最短那列的高度
self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));
/**返回indexPath位置的cell的布局属性*/
return attrs;
}










