collectionView實作瀑布流效果,隻需要重寫layout即可。
設定代理(根據寬度計算出cell高度) 不在layout中計算,而是在代理中計算,是為了保證cell上得圖檔不變形
@class WTKWaterFlowLayout;
@protocol WTKWaterFlowLayoutDelegate <NSObject>
- (CGFloat)waterFlowLayout:(WTKWaterFlowLayout *)waterFlowLayout cellWidth:(CGFloat)width atIndexPath:(NSIndexPath *)indexPaht;
@end
@interface WTKWaterFlowLayout : UICollectionViewLayout
重寫layout的幾個方法
1、
- (void)prepareLayout
{
for (int i = 0; i<3; i++)
{
NSString *key = [NSString stringWithFormat:@"%d",i];
self.maxDic[key] = @0;
}
// 第0區 cell的個數
NSInteger count = [self.collectionView numberOfItemsInSection:0];
for (int i = 0; i<count; i++)
{
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
[self.attributesArray addObject:attributes];
}
}
2、設定collectionView的 contentSize
- (CGSize)collectionViewContentSize
{
__block NSString *maxColumn = @"0";
[self.maxDic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
if ([self.maxDic[maxColumn] floatValue]<[obj floatValue])
{
maxColumn = key;
}
}];
return CGSizeMake(self.collectionView.bounds.size.width, [self.maxDic[maxColumn] floatValue]);
}
3、設定attributesArray
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
return self.attributesArray;
}
其中最重要的方法
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
// 找出最短的一行
__block NSString *minColumn = @"0";
[self.maxDic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
if ([self.maxDic[minColumn] floatValue]>[obj floatValue])
{
minColumn = key;
}
}];
// cell 寬度
CGFloat width = (self.collectionView.frame.size.width - self.sectionInsets.left - self.sectionInsets.right - (self.columnCount - 1)*self.columnMargin)/self.columnCount;
// 高度根據代理方法計算
CGFloat height = [self.delegate waterFlowLayout:self cellWidth:width atIndexPath:indexPath] + 30;
CGFloat x = self.sectionInsets.left + (width + self.columnMargin) * [minColumn floatValue] ;
CGFloat y = self.rowMargin + [self.maxDic[minColumn] floatValue];
// 更新maxDic
self.maxDic[minColumn] = @(y +height);
attributes.frame = CGRectMake(x, y, width, height);
return attributes;
}
其中self.maxDic存放每一列的高度。self.attributesArray 存放attributes。 self.columnMargin為cell的間距 self.columnCount為列數