瀑布流 (擴展性強 設置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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容