瀑布流布局可能是大家最不想見到的布局,因為這種布局不宜想到解決的辦法。下邊就跟我來秒了它。
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