以下是方法实现的代码
#import <UIKit/UIKit.h>
@interface XMFWaterFall : UICollectionViewLayout
// 一行的列数
@property (nonatomic, assign) NSUInteger colCount;
// collection内边距
@property (nonatomic, assign) UIEdgeInsets edgeInsets;
// cell的间距
@property (nonatomic, assign) CGFloat space;
// item宽
@property (nonatomic, assign) CGFloat itemWidth;
// 高度
@property (nonatomic, copy) CGFloat (^heightAction) (NSIndexPath *indexPath);
@end
#import "XMFWaterFall.h"
@interface XMFWaterFall ()
@property (nonatomic, strong) NSMutableArray<UICollectionViewLayoutAttributes *> *attributes;
@end
@implementation XMFWaterFall
// 第一步
- (void)prepareLayout {
[super prepareLayout];
NSUInteger totalCellNum = [self.collectionView numberOfItemsInSection:0];
_attributes = [NSMutableArray<UICollectionViewLayoutAttributes *> arrayWithCapacity: totalCellNum];
NSIndexPath *indexPath;
for (int i = 0; i < totalCellNum; i++) {
indexPath = [NSIndexPath indexPathForItem:i inSection:0];
[_attributes addObject: [self layoutAttributesForItemAtIndexPath:indexPath]];
}
}
// 第二步
- (CGSize)collectionViewContentSize {
CGFloat totalCellWidth = _edgeInsets.left + _edgeInsets.right + (_colCount - 1) * _space +_colCount * _itemWidth;
return CGSizeMake(totalCellWidth, [self getMaxY] + _edgeInsets.bottom);
}
// 第三步
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
NSUInteger currentColum = indexPath.row % _colCount;
CGFloat cellX = _edgeInsets.left + currentColum * (_itemWidth + _space); // cell的x
// cell的y
CGFloat cellY;
if (indexPath.row + 1 > _colCount) {
cellY = CGRectGetMaxY(_attributes[indexPath.row - _colCount].frame) + _space;
}
else
cellY = _edgeInsets.top;
// cell的高
CGFloat cellH = 0.0;
if (_heightAction) {
cellH = _heightAction(indexPath);
}
attributes.frame = CGRectMake(cellX, cellY, _itemWidth, cellH);
return attributes;
}
// 第三步
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
return _attributes;
}
/**
* 获得最大y值
*/
- (CGFloat)getMaxY {
NSUInteger totalCellNum = [self.collectionView numberOfItemsInSection:0];
NSInteger lastLenght = totalCellNum % _colCount;
if (lastLenght == 0) lastLenght = _colCount;
__block CGFloat tempY = 0.0;
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(_attributes.count - lastLenght, lastLenght)];
[_attributes enumerateObjectsAtIndexes:indexSet options:NSEnumerationConcurrent usingBlock:^(UICollectionViewLayoutAttributes * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
tempY = MAX(tempY, CGRectGetMaxY(obj.frame));
}];
return tempY;
}
@end
这是一种简单实现瀑布流的方法,注释不多,如有不懂可以在QQ群 389400205上问我
以下是我的github可以在此下载代码
点击打开链接