瀑布流 (扩展性强 设置item的高度简单 设置展示的列数方便)
瀑布流布局可能是大家最不想见到的布局,因为这种布局不宜想到解决的办法。下边就跟我来秒了它。
1.分析这种布局
1.1 我们要用那种控制器来完成?
1.2 item的高度不一样,怎么解决?
1.3 下一个item摆放的位置,为上一列item高度最短的下面,怎么找到上一列高度最短的item?
1.4 怎么设置瀑布流内容的尺寸?
瀑布流布局分析
2.解决问题
2.1 选择用 UICollectionView 控制器来完成。
2.2 我们来解决item摆放的位置。
2.2.1 我们可以重写 UICollectionViewFlowLayout 布局来完成。
1.准备布局
//初始化
- (instancetype)init {
if(self= [superinit]) {
//内边距
self.sectionInset=UIEdgeInsetsMake(kMaragr,kMaragr,kMaragr,kMaragr);
self.minimumLineSpacing=kMaragr;
self.minimumInteritemSpacing=kMaragr;
}
returnself;
}
//准备布局
- (void)prepareLayout {
// ***一定调用父类
[superprepareLayout];
//0.列数
self.cols= [self.delegaterespondsToSelector:@selector(numberOfCols:)] ? [self.delegatenumberOfCols:self] : 3;
//1.获取所有cell个数
NSIntegercellCount = [self.collectionViewnumberOfItemsInSection:0];
//2.创建cell属性
CGFloatcellW = (self.collectionView.bounds.size.width-self.sectionInset.left-self.sectionInset.right- (self.cols- 1) *kMaragr) /self.cols;
for(NSIntegeri = 0; i < cellCount; i++) {
//2.1创建indexPath
NSIndexPath*indexPath = [NSIndexPathindexPathForItem:iinSection:0];
//2.2创建attributes
UICollectionViewLayoutAttributes*attributes = [UICollectionViewLayoutAttributeslayoutAttributesForCellWithIndexPath:indexPath];
//2.3设置cell的frame
__blockCGFloatminCellH =MAXFLOAT;
__blockNSUIntegerindex = 0;
//利用枚举遍历来获取最短的item
[self.cellHsenumerateObjectsUsingBlock:^(NSNumber*obj,NSUIntegeridx,BOOL*_Nonnullstop) {
//2.4寻找最短的一列
if(obj.doubleValue< minCellH) {
minCellH = obj.doubleValue;
index = idx;
}
}];
//2.5获取最短一列的行数
CGFloatCellX =self.sectionInset.left+ index * (cellW +self.minimumInteritemSpacing);
CGFloatCellY = minCellH;
CGFloatCellH = [self.delegatewaterfallCellH:selfindexPath:indexPath];
attributes.frame=CGRectMake(CellX, CellY, cellW, CellH);
//2.6保存
self.cellHs[index] = [NSNumbernumberWithFloat:(minCellH + + CellH +self.minimumLineSpacing)];
//self.cellHs[index] = [NSNumber numberWithFloat:CGRectGetMaxY(attributes.frame) + self.minimumLineSpacing];
[self.attrsaddObject:attributes];
}
}
2. 返回item属性 瀑布流内容尺寸
//返回cell属性的数据
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
returnself.attrs;
}
//集合视图的内容尺寸
- (CGSize)collectionViewContentSize {
__blockCGFloatmaxCellH = 0;
[self.cellHsenumerateObjectsUsingBlock:^(NSNumber*obj,NSUIntegeridx,BOOL*_Nonnullstop) {
//2.4寻找最长的一列
if(obj.floatValue> maxCellH) {
maxCellH = obj.floatValue;
}
}];
returnCGSizeMake(0, maxCellH +self.minimumLineSpacing-self.sectionInset.top);
}
3. 使用代理来控制展示的列数和每一个item的高度
#import
@classWaterfallFlowLayout;
//协议
@protocolWaterfallFlowLayoutDelegate
@optional
//展示多少列
- (NSInteger)numberOfCols:(WaterfallFlowLayout*)waterfall;
@required
//cell的高度
- (CGFloat)waterfallCellH:(WaterfallFlowLayout*)waterfall indexPath:(NSIndexPath*)indexPath;
@end
@interfaceWaterfallFlowLayout :UICollectionViewFlowLayout
///代理
@property(nonatomic,weak)id delegate;
@end
4.在控制器里调用
#import"WaterfallController.h"
#import"WaterfallFlowLayout.h"
//cell重用标识符
staticNSString*constkCellId =@"kCellId";
@interfaceWaterfallController()
///集合视图
@property(nonatomic,strong)UICollectionView*collection;
@end
@implementationWaterfallController
- (void)viewDidLoad {
[superviewDidLoad];
//创建集合视图
[selfcreateCollection];
}
#pragma mark -创建集合视图
- (void)createCollection {
//1.创建布局
WaterfallFlowLayout*flowlayout = [[WaterfallFlowLayoutalloc]init];
//代理
flowlayout.delegate=self;
//2.创建集合视图
self.collection= [[UICollectionViewalloc]initWithFrame:self.view.boundscollectionViewLayout:flowlayout];
self.collection.backgroundColor= [UIColorwhiteColor];
//代理
self.collection.dataSource=self;
//注册cell
[self.collectionregisterClass:[UICollectionViewCellclass]forCellWithReuseIdentifier:kCellId];
[self.viewaddSubview:self.collection];
}
#pragma mark -数据源代理
- (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section {
return50;
}
- (__kindofUICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath {
UICollectionViewCell*cell = [collectionViewdequeueReusableCellWithReuseIdentifier:kCellIdforIndexPath:indexPath];
cell.backgroundColor= [UIColorcolorWithRed:arc4random_uniform(256) / 255.0green:arc4random_uniform(256) / 255.0blue:arc4random_uniform(256) / 255.0alpha:1.0];
returncell;
}
#pragma mark -布局的代理
- (CGFloat)waterfallCellH:(WaterfallFlowLayout*)waterfall indexPath:(NSIndexPath*)indexPath {
return arc4random_uniform(50) + 50;
}
//可选(默认三列)设置展示的列数
- (NSInteger)numberOfCols:(WaterfallFlowLayout*)waterfall {
return 2;
}
@end
结果 展示两列
希望对大家有所帮助,如果有错误,请望指出,共同改正。
Demo地址: 瀑布流Demo