用factory模式解决瀑布流中展示不同风格的item
由于项目的需求,最近做了一个可以定义item不同的高度,并且可以显示不同item的瀑布流,拿出来供大家参考。
#import <UIKit/UIKit.h>
typedef CGFloat(^itemHeightBlock)(NSIndexPath* index);
@interface WaterfallColectionLayout : UICollectionViewLayout
@property(nonatomic,strong )itemHeightBlock heightBlock ;
-(instancetype)initWithItemsHeightBlock:(itemHeightBlock)block;
@end
#import "WaterfallColectionLayout.h"
#define colMargin 5
#define colCount 4
#define rolMargin 5
@interface WaterfallColectionLayout ()
//数组存放每列的总高度
@property(nonatomic,strong)NSMutableArray* colsHeight;
//单元格宽度
@property(nonatomic,assign)CGFloat colWidth;
@end
@implementation WaterfallColectionLayout
-(instancetype)initWithItemsHeightBlock:(itemHeightBlock)block{
if ([super init]) {
self.heightBlock = block;
}
return self;
}
-(void)prepareLayout{
[super prepareLayout];
self.colWidth =( self.collectionView.frame.size.width - (colCount+1)*colMargin )/colCount;
self.colsHeight = nil;
}
-(CGSize)collectionViewContentSize{
NSNumber * longest = self.colsHeight[0];
for (NSInteger i =0;i<self.colsHeight.count;i++) {
NSNumber* rolHeight = self.colsHeight[i];
if(longest.floatValue<rolHeight.floatValue){
longest = rolHeight;
}
}
return CGSizeMake(self.collectionView.frame.size.width, longest.floatValue);
}
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewLayoutAttributes* attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
NSNumber * shortest = self.colsHeight[0];
NSInteger shortCol = 0;
for (NSInteger i =0;i<self.colsHeight.count;i++) {
NSNumber* rolHeight = self.colsHeight[i];
if(shortest.floatValue>rolHeight.floatValue){
shortest = rolHeight;
shortCol=i;
}
}
CGFloat x = (shortCol+1)*colMargin+ shortCol * self.colWidth;
CGFloat y = shortest.floatValue+colMargin;
//获取cell高度
CGFloat height=0;
NSAssert(self.heightBlock!=nil, @"未实现计算高度的block ");
if(self.heightBlock){
height = self.heightBlock(indexPath);
}
attr.frame= CGRectMake(x, y, self.colWidth, height);
self.colsHeight[shortCol]=@(shortest.floatValue+colMargin+height);
return attr;
}
-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
NSMutableArray* array = [NSMutableArray array];
NSInteger items = [self.collectionView numberOfItemsInSection:0];
for (int i = 0; i<items;i++) {
UICollectionViewLayoutAttributes* attr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
[array addObject:attr];
}
return array;
}
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
return YES;
}
-(NSMutableArray *)colsHeight{
if(!_colsHeight){
NSMutableArray * array = [NSMutableArray array];
for(int i =0;i<colCount;i++){
//这里可以设置初始高度
[array addObject:@(0)];
}
_colsHeight = [array mutableCopy];
}
return _colsHeight;
}
@end
奉上demo地址:https://github.com/cocofcw/WaterfallCollectionLayout-master