瀑布流的实现
实现一个自定义的瀑布流UICollectionViewLayout的常规做法是继承UICollectionViewLayout,然后重载下列方法
// 布局计算
-(void)prepareLayout
// 返回collectionView的内容尺寸
-(CGSize)collectionViewContentSize
/**
* 返回rect中的所有元素的布局属性
* 返回的是包含UICollectionViewLayoutAttributes的数组
* UICollectionViewLayoutAttributes可以是cell、SupplementaryView或者DecorationView的信息通过不同的UICollectionViewLayoutAttributes初始化方法可以得到不同类型的UICollectionViewLayoutAttributes
* + (instancetype)layoutAttributesForCellWithIndexPath:(NSIndexPath *)indexPath
* + (instancetype)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind withIndexPath:(NSIndexPath *)indexPath
* + (instancetype)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind withIndexPath:(NSIndexPath *)indexPath
*/
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
// 返回对应于indexPath的位置的cell的布局属性
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path
// 返回对应于indexPath位置的SupplementaryView的布局属性,如果没有SupplementaryView可不重载
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;
// 返回对应于indexPath位置的DecorationView的布局属性,如果没有DecorationView可不重载
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString*)elementKind atIndexPath:(NSIndexPath *)indexPath;
DMWaterfallFlowLayout.h
#import <UIKit/UIKit.h>
@class DMWaterfallFlowLayout;
@protocol DMWaterfallFlowLayoutDelegate <NSObject>
@required
/**
* cell 高度
*/
- (CGFloat)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout heightForItemAtIndexPath:(NSIndexPath *)indexPath itemWidth:(CGFloat)width;
@optional
/**
* 分区 sectionHeader 高度
*/
- (CGFloat)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout heightForHeaderInSection:(NSInteger)section;
/**
* 分区 sectionFooter 高度
*/
- (CGFloat)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout heightForFooterInSection:(NSInteger)section;
/**
* 分区 列数
*/
- (NSInteger)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout columnCountInSection:(NSInteger)section;
/**
* 分区 列间距
*/
- (CGFloat)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout columnMarginInSection:(NSInteger)section;
/**
* 分区 行间距
*/
- (CGFloat)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout rowMarginInSection:(NSInteger)section;
/**
* 分区 UIEdgeInsets
*/
- (UIEdgeInsets)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout edgeInsetsInSection:(NSInteger)section;
@end
@interface DMWaterfallFlowLayout : UICollectionViewFlowLayout
@property (nonatomic, weak) id<DMWaterfallFlowLayoutDelegate> delegate;
- (CGFloat)headerHeightInSection:(NSInteger)section;
- (CGFloat)footerHeightInSection:(NSInteger)section;
- (NSInteger)columnCountInSection:(NSInteger)section;
- (CGFloat)columnMarginInSection:(NSInteger)section;
- (CGFloat)rowMarginInSection:(NSInteger)section;
- (UIEdgeInsets)edgeInsetsInSection:(NSInteger)section;
@end
DMWaterfallFlowLayout.m
#import "DMWaterfallFlowLayout.h"
/** section Header 高度 */
static const CGFloat DMDefaultHeaderHeight = 0;
/** section Footer 高度 */
static const CGFloat DMDefaultFooterHeight = 0;
/** 列数 */
static const NSInteger DMDefaultColumCount = 2;
/** 每一列间距 */
static const CGFloat DMDefaultColumMargin = 10;
/** 每一行间距 */
static const CGFloat DMDefaultRowMargin = 10;
/** 边缘间距 */
static const UIEdgeInsets DMDefaultEdgeInsets = {10,0,10,0};
@interface DMWaterfallFlowLayout ()
/** 布局属性数组 */
@property (nonatomic, strong) NSMutableArray *attrsArray;
/** 存放section数组,每一个section数组中存放列的当前高度 */
@property (nonatomic, strong) NSMutableArray *columnHeightArray;
@end
@implementation DMWaterfallFlowLayout
#pragma mark - life cycle
- (void)prepareLayout
{
[super prepareLayout];
//如果刷新布局就会重新调用prepareLayout这个方法,所以要先把高度数组清空
[self.columnHeightArray removeAllObjects];
[self.attrsArray removeAllObjects];
NSInteger sectionNum = [self.collectionView numberOfSections];
for (NSInteger sectionIndex = 0; sectionIndex < sectionNum; sectionIndex++) {
// 获取前一个section的高度
CGFloat tmpBottom = 0;
if (sectionIndex != 0) {
NSArray *beforeColumnHeightArray = [self.columnHeightArray objectAtIndex:sectionIndex - 1];
for (NSNumber *curNum in beforeColumnHeightArray) {
if (tmpBottom < [curNum floatValue]) {
tmpBottom = [curNum floatValue];
}
}
}
// 1.先判断是否存在section Header
CGFloat headerHeight = [self headerHeightInSection:sectionIndex];
if (headerHeight > 0) {
//获取UICollectionElementKindSectionHeader对应的布局属性
NSIndexPath *curIndexPath = [NSIndexPath indexPathForRow:0 inSection:sectionIndex];
UICollectionViewLayoutAttributes *layoutHeader = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:curIndexPath];
[self.attrsArray addObject:layoutHeader];
}
// section edge inset
UIEdgeInsets sectionEdgeInsets = [self edgeInsetsInSection:sectionIndex];
// cell
NSInteger tmpColumnCount = [self columnCountInSection:sectionIndex];
NSMutableArray *tmpColumnHeightArray = [[NSMutableArray alloc] init];
for (NSInteger columnIndex = 0; columnIndex < tmpColumnCount; columnIndex++) {
[tmpColumnHeightArray addObject:[NSNumber numberWithFloat:tmpBottom + headerHeight + sectionEdgeInsets.top]];
}
[self.columnHeightArray addObject:tmpColumnHeightArray];
NSInteger itemsNum = [self.collectionView numberOfItemsInSection:sectionIndex];
for (NSInteger itemIndex = 0; itemIndex < itemsNum; itemIndex++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:itemIndex inSection:sectionIndex];
//获取indexPath 对应cell 的布局属性
UICollectionViewLayoutAttributes *attr = [self layoutAttributesForItemAtIndexPath:indexPath];
[self.attrsArray addObject:attr];
}
if (sectionEdgeInsets.bottom > 0) {
for (NSInteger columnIndex = 0; columnIndex < tmpColumnCount; columnIndex++) {
// 更新数组中列的当前高度
NSNumber *curHeight = tmpColumnHeightArray[columnIndex];
tmpColumnHeightArray[columnIndex] = [NSNumber numberWithFloat:curHeight.doubleValue + sectionEdgeInsets.bottom];
}
}
// section Footer
CGFloat footerHeight = [self footerHeightInSection:sectionIndex];
if (footerHeight > 0) {
//获取UICollectionElementKindSectionFooter对应的布局属性
NSIndexPath *curIndexPath = [NSIndexPath indexPathForRow:0 inSection:sectionIndex];
UICollectionViewLayoutAttributes *layoutFooter = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter atIndexPath:curIndexPath];
[self.attrsArray addObject:layoutFooter];
for (NSInteger columnIndex = 0; columnIndex < tmpColumnCount; columnIndex++) {
// 更新数组中列的当前高度
NSNumber *curHeight = tmpColumnHeightArray[columnIndex];
tmpColumnHeightArray[columnIndex] = [NSNumber numberWithFloat:curHeight.doubleValue + footerHeight];
}
}
}
}
/**
* 返回supplementaryView对应的布局属性
*/
- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes *tempAttr = nil;
if ([elementKind isEqualToString:UICollectionElementKindSectionHeader]) {
UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:elementKind withIndexPath:indexPath];
NSInteger sectionIndex = indexPath.section;
CGFloat headerOriginY = 0;
// 前一个section的高度
if (sectionIndex != 0) {
NSArray *beforeColumnHeightArray = [self.columnHeightArray objectAtIndex:sectionIndex - 1];
for (NSNumber *curNum in beforeColumnHeightArray) {
if (headerOriginY < [curNum floatValue]) {
headerOriginY = [curNum floatValue];
}
}
}
CGFloat headerHeight = [self headerHeightInSection:sectionIndex];
// 设置frame
attr.frame = CGRectMake(0, headerOriginY, [UIScreen mainScreen].bounds.size.width, headerHeight);
tempAttr = attr;
} else if ([elementKind isEqualToString:UICollectionElementKindSectionFooter]) {
NSInteger sectionIndex = indexPath.section;
CGFloat footerOriginY = 0;
NSArray *curColumnHeightArray = [self.columnHeightArray objectAtIndex:sectionIndex];
for (NSNumber *curNum in curColumnHeightArray) {
if (footerOriginY < [curNum floatValue]) {
footerOriginY = [curNum floatValue];
}
}
UICollectionViewLayoutAttributes *layoutFooter = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter withIndexPath:indexPath];
CGFloat footerHeight = [self footerHeightInSection:sectionIndex];
// 设置frame
layoutFooter.frame = CGRectMake(0, footerOriginY, [UIScreen mainScreen].bounds.size.width, footerHeight);
tempAttr = layoutFooter;
}
return tempAttr;
}
/**
* 返回indexPath 位置cell对应的布局属性
*/
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
NSInteger sectionIndex = indexPath.section;
NSMutableArray *curColumnHeightArray = [self.columnHeightArray objectAtIndex:sectionIndex];
// 获取前一个section的高度
CGFloat tmpBottom = 0;
if (sectionIndex != 0) {
NSArray *beforeColumnHeightArray = [self.columnHeightArray objectAtIndex:sectionIndex - 1];
for (NSNumber *curNum in beforeColumnHeightArray) {
if (tmpBottom < [curNum floatValue]) {
tmpBottom = [curNum floatValue];
}
}
}
// 当前section的section header
CGFloat headerHeight = [self headerHeightInSection:sectionIndex];
if (headerHeight > 0) {
tmpBottom += headerHeight;
}
// section edge inset
UIEdgeInsets sectionEdgeInsets = [self edgeInsetsInSection:sectionIndex];
CGFloat sectionColumnMargin = [self columnMarginInSection:sectionIndex];
CGFloat sectionRowMargin = [self rowMarginInSection:sectionIndex];
//使用for循环,找出高度最短的那一列
//最短高度的列(即存放当前cell的列)
NSInteger destColumn = 0;
CGFloat minColumnHeight = [curColumnHeightArray[0] doubleValue];
NSInteger tmpColumnCount = [self columnCountInSection:sectionIndex];
for (NSInteger i = 1; i < tmpColumnCount; i++) {
CGFloat columnHeight = [curColumnHeightArray[i] doubleValue];
if (minColumnHeight > columnHeight) {
minColumnHeight = columnHeight;
destColumn = I;
}
}
//cell item的宽度
CGFloat w = (self.collectionView.frame.size.width - sectionEdgeInsets.left - sectionEdgeInsets.right - (tmpColumnCount - 1) * sectionColumnMargin ) / tmpColumnCount;
//cell item的高度
CGFloat h = [self.delegate waterfallFlowLayout:self heightForItemAtIndexPath:indexPath itemWidth:w];
//cell item的起点x
CGFloat x = sectionEdgeInsets.left + destColumn * (w + sectionColumnMargin);
//cell item的起点y
CGFloat y = minColumnHeight ;
// 当前cell不是分区的第一行cell 时 添加一个行Margin
if (y != tmpBottom + sectionEdgeInsets.top) {
y += sectionRowMargin;
}
// 设置frame
attr.frame = CGRectMake(x,y,w,h);
// 修改数组中当前列的高度
curColumnHeightArray[destColumn] = [NSNumber numberWithFloat:y+ h];
return attr;
}
/**
* 决定UICollectionView的排布
*/
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
return self.attrsArray;
}
/**
* 可滑动范围
*/
- (CGSize)collectionViewContentSize
{
CGFloat maxHeight = 0;
NSInteger sectionNum = [self.collectionView numberOfSections];
if (sectionNum > 0) {
NSArray *curColumnHeightArray = [self.columnHeightArray objectAtIndex:sectionNum - 1];
for (NSNumber *curNum in curColumnHeightArray) {
if (maxHeight < [curNum floatValue]) {
maxHeight = [curNum floatValue];
}
}
}
return CGSizeMake(0, maxHeight);
}
#pragma mark - public method
- (CGFloat)headerHeightInSection:(NSInteger)section
{
CGFloat tempHeaderHeight = 0;
if (self.delegate && [self.delegate respondsToSelector:@selector(waterfallFlowLayout:heightForHeaderInSection:)]) {
tempHeaderHeight = [self.delegate waterfallFlowLayout:self heightForHeaderInSection:section];
} else {
tempHeaderHeight = DMDefaultHeaderHeight;
}
return tempHeaderHeight;
}
- (CGFloat)footerHeightInSection:(NSInteger)section
{
CGFloat tempHeaderHeight = 0;
if (self.delegate && [self.delegate respondsToSelector:@selector(waterfallFlowLayout:heightForFooterInSection:)]) {
tempHeaderHeight = [self.delegate waterfallFlowLayout:self heightForFooterInSection:section];
} else {
tempHeaderHeight = DMDefaultFooterHeight;
}
return tempHeaderHeight;
}
- (NSInteger)columnCountInSection:(NSInteger)section
{
NSInteger tempColumn = 0;
if (self.delegate && [self.delegate respondsToSelector:@selector(waterfallFlowLayout:columnCountInSection:)]) {
tempColumn = [self.delegate waterfallFlowLayout:self columnCountInSection:section];
} else {
tempColumn = DMDefaultColumCount;
}
return tempColumn;
}
- (CGFloat)columnMarginInSection:(NSInteger)section
{
CGFloat tempColumnMargin = 0;
if (self.delegate && [self.delegate respondsToSelector:@selector(waterfallFlowLayout:columnMarginInSection:)]) {
tempColumnMargin = [self.delegate waterfallFlowLayout:self columnMarginInSection:section];
} else {
tempColumnMargin = DMDefaultColumMargin;
}
return tempColumnMargin;
}
- (CGFloat)rowMarginInSection:(NSInteger)section
{
CGFloat tempRowMargin = 0;
if (self.delegate && [self.delegate respondsToSelector:@selector(waterfallFlowLayout:rowMarginInSection:)]) {
tempRowMargin = [self.delegate waterfallFlowLayout:self rowMarginInSection:section];
} else {
tempRowMargin = DMDefaultRowMargin;
}
return tempRowMargin;
}
- (UIEdgeInsets)edgeInsetsInSection:(NSInteger)section
{
UIEdgeInsets tempEdgeInset = UIEdgeInsetsZero;
if (self.delegate && [self.delegate respondsToSelector:@selector(waterfallFlowLayout:edgeInsetsInSection:)]) {
tempEdgeInset = [self.delegate waterfallFlowLayout:self edgeInsetsInSection:section];
} else {
tempEdgeInset = DMDefaultEdgeInsets;
}
return tempEdgeInset;
}
#pragma mark - getter and setter
- (NSMutableArray *)attrsArray
{
if (_attrsArray == nil) {
_attrsArray = [[NSMutableArray alloc] init];
}
return _attrsArray;
}
- (NSMutableArray *)columnHeightArray
{
if (_columnHeightArray == nil) {
_columnHeightArray = [[NSMutableArray alloc] init];
}
return _columnHeightArray;
}
@end
注释已经很详细了
看一下如何使用,实例如下
#import "DMFunctionWaterfallViewController.h"
#import "DMWaterfallFlowLayout.h"
#import "DMSectionHeaderCollectionReusableView.h"
#import "DMSectionFooterCollectionReusableView.h"
#import "DMNormalCollectionViewCell.h"
#import "DMWaterfallCollectionViewCell.h"
static NSString * const kDMSectionHeaderCollectionReusableViewIdentifier = @"kDMSectionHeaderCollectionReusableViewIdentifier";
static NSString * const kDMSectionFooterCollectionReusableViewIdentifier = @"kDMSectionFooterCollectionReusableViewIdentifier";
static NSString * const kDMNormalCollectionViewCellIdentifier = @"kDMNormalCollectionViewCellIdentifier";
static NSString * const kDMWaterfallCollectionViewCellIdentifier = @"kDMWaterfallCollectionViewCellIdentifier";
@interface DMFunctionWaterfallViewController () <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, DMWaterfallFlowLayoutDelegate>
/** UI */
@property (nonatomic, strong) UICollectionView *myCollectionView;
/** DATA */
@property (nonatomic, strong) NSMutableArray *dataArray;
@end
@implementation DMFunctionWaterfallViewController
#pragma mark - life cycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.title = @"瀑布流";
[self initData];
[self.view addSubview:self.myCollectionView];
}
- (void)initData
{
{
NSMutableArray *sectionOneArray = [[NSMutableArray alloc] init];
{
DMNormalCollectionViewCellModel *modelOne = [[DMNormalCollectionViewCellModel alloc] init];
modelOne.imageName = @"picOne";
[sectionOneArray addObject:modelOne];
}
{
DMNormalCollectionViewCellModel *modelTwo = [[DMNormalCollectionViewCellModel alloc] init];
modelTwo.imageName = @"picTow";
[sectionOneArray addObject:modelTwo];
}
[self.dataArray addObject:sectionOneArray];
}
{
NSMutableArray *sectionTwoArray = [[NSMutableArray alloc] init];
{
DMWaterfallCollectionViewCellModel *modelOne = [[DMWaterfallCollectionViewCellModel alloc] init];
modelOne.imageName = @"YY1";
modelOne.ratioNum = [NSNumber numberWithFloat:1/1.5];
modelOne.numStr = @"1";
[sectionTwoArray addObject:modelOne];
}
{
DMWaterfallCollectionViewCellModel *modelTwo = [[DMWaterfallCollectionViewCellModel alloc] init];
modelTwo.imageName = @"YY2";
modelTwo.ratioNum = [NSNumber numberWithFloat:1.5/1.0];
modelTwo.numStr = @"2";
[sectionTwoArray addObject:modelTwo];
}
{
DMWaterfallCollectionViewCellModel *modelThree = [[DMWaterfallCollectionViewCellModel alloc] init];
modelThree.imageName = @"YY3";
modelThree.ratioNum = [NSNumber numberWithFloat:1/1.6];
modelThree.numStr = @"3";
[sectionTwoArray addObject:modelThree];
}
{
DMWaterfallCollectionViewCellModel *modelFour = [[DMWaterfallCollectionViewCellModel alloc] init];
modelFour.imageName = @"YY4";
modelFour.ratioNum = [NSNumber numberWithFloat:1/1.7];
modelFour.numStr = @"4";
[sectionTwoArray addObject:modelFour];
}
{
DMWaterfallCollectionViewCellModel *modelThree = [[DMWaterfallCollectionViewCellModel alloc] init];
modelThree.imageName = @"YY5";
modelThree.ratioNum = [NSNumber numberWithFloat:1/1.8];
modelThree.numStr = @"5";
[sectionTwoArray addObject:modelThree];
}
[self.dataArray addObject:sectionTwoArray];
}
{
NSMutableArray *sectionThreeArray = [[NSMutableArray alloc] init];
{
DMNormalCollectionViewCellModel *modelOne = [[DMNormalCollectionViewCellModel alloc] init];
modelOne.imageName = @"mountain1";
[sectionThreeArray addObject:modelOne];
}
{
DMNormalCollectionViewCellModel *modelTwo = [[DMNormalCollectionViewCellModel alloc] init];
modelTwo.imageName = @"mountain2";
[sectionThreeArray addObject:modelTwo];
}
{
DMNormalCollectionViewCellModel *modelThree = [[DMNormalCollectionViewCellModel alloc] init];
modelThree.imageName = @"mountain3";
[sectionThreeArray addObject:modelThree];
}
{
DMNormalCollectionViewCellModel *modelFour = [[DMNormalCollectionViewCellModel alloc] init];
modelFour.imageName = @"mountain4";
[sectionThreeArray addObject:modelFour];
}
[self.dataArray addObject:sectionThreeArray];
}
}
#pragma mark - UICollectionViewDataSource method
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
NSInteger sectionNum = 0;
sectionNum = [self.dataArray count];
return sectionNum;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
NSInteger itemsNum = 0;
NSArray *itemsArray = [self.dataArray objectAtIndex:section];
itemsNum = [itemsArray count];
return itemsNum;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = nil;
NSInteger sectionIndex = indexPath.section;
NSInteger rowIndex = indexPath.row;
NSArray *tmpDataArray = [self.dataArray objectAtIndex:sectionIndex];
if (sectionIndex == 0) {
DMNormalCollectionViewCell * tmpCell = [collectionView dequeueReusableCellWithReuseIdentifier:kDMNormalCollectionViewCellIdentifier forIndexPath:indexPath];
DMNormalCollectionViewCellModel *dataModel = [tmpDataArray objectAtIndex:rowIndex];
[tmpCell setDataModel:dataModel];
cell = tmpCell;
} else if (sectionIndex == 1) {
DMWaterfallCollectionViewCell *tmpCell = [collectionView dequeueReusableCellWithReuseIdentifier:kDMWaterfallCollectionViewCellIdentifier forIndexPath:indexPath];
DMWaterfallCollectionViewCellModel *dataModel = [tmpDataArray objectAtIndex:rowIndex];
[tmpCell setDataModel:dataModel];
cell = tmpCell;
} else {
DMNormalCollectionViewCell * tmpCell = [collectionView dequeueReusableCellWithReuseIdentifier:kDMNormalCollectionViewCellIdentifier forIndexPath:indexPath];
DMNormalCollectionViewCellModel *dataModel = [tmpDataArray objectAtIndex:rowIndex];
[tmpCell setDataModel:dataModel];
cell = tmpCell;
}
return cell;
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
UICollectionReusableView *tmpView = nil;
NSInteger sectionIndex = indexPath.section;
if (sectionIndex == 0) {
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
DMSectionHeaderCollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:kDMSectionHeaderCollectionReusableViewIdentifier forIndexPath:indexPath];
[headerView updateStr:@"第一个分区头部"];
headerView.backgroundColor = [UIColor redColor];
tmpView = headerView;
} else if ([kind isEqualToString:UICollectionElementKindSectionFooter]) {
DMSectionHeaderCollectionReusableView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:kDMSectionFooterCollectionReusableViewIdentifier forIndexPath:indexPath];
[footerView updateStr:@"第一个分区尾部"];
footerView.backgroundColor = [UIColor yellowColor];
tmpView = footerView;
}
} else if (sectionIndex == 1) {
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
DMSectionHeaderCollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:kDMSectionHeaderCollectionReusableViewIdentifier forIndexPath:indexPath];
[headerView updateStr:@"第二个分区头部"];
headerView.backgroundColor = [UIColor greenColor];
tmpView = headerView;
} else if ([kind isEqualToString:UICollectionElementKindSectionFooter]) {
DMSectionHeaderCollectionReusableView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:kDMSectionFooterCollectionReusableViewIdentifier forIndexPath:indexPath];
[footerView updateStr:@"第二个分区尾部"];
footerView.backgroundColor = [UIColor purpleColor];
tmpView = footerView;
}
}
return tmpView;
}
#pragma mark - UICollectionViewDelegate method
#pragma mark - DMWaterfallFlowLayoutDelegate method
- (CGFloat)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout heightForItemAtIndexPath:(NSIndexPath *)indexPath itemWidth:(CGFloat)width
{
NSInteger sectionIndex = indexPath.section;
CGFloat itemHeight = 0;
if (sectionIndex == 0) {
itemHeight = [DMNormalCollectionViewCell cellHeight];
} else if (sectionIndex == 1) {
NSInteger sectionIndex = indexPath.section;
NSInteger rowIndex = indexPath.row;
NSArray *tmpDataArray = [self.dataArray objectAtIndex:sectionIndex];
DMWaterfallCollectionViewCellModel *dataModel = [tmpDataArray objectAtIndex:rowIndex];
itemHeight = width / [dataModel.ratioNum floatValue];
} else if (sectionIndex == 2) {
itemHeight = [DMNormalCollectionViewCell cellHeight];
}
return itemHeight;
}
/**
* sectionHeader 高度
*/
- (CGFloat)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout heightForHeaderInSection:(NSInteger)section
{
CGFloat headerHeight = 0;
if (section == 0) {
headerHeight = 60;
} else if (section == 1) {
headerHeight = 40;
}
return headerHeight;
}
/**
* sectionFooter 高度
*/
- (CGFloat)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout heightForFooterInSection:(NSInteger)section
{
CGFloat footerHeight = 0;
if (section == 0) {
footerHeight = 50;
} else if (section == 1) {
footerHeight = 40;
}
return footerHeight;
}
/**
* 列数
*/
- (NSInteger)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout columnCountInSection:(NSInteger)section
{
NSInteger columnCount = 0;
if (section == 0) {
columnCount = 1;
} else if (section == 1) {
columnCount = 2;
} else {
columnCount = 1;
}
return columnCount;
}
/**
* 列间距
*/
- (CGFloat)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout columnMarginInSection:(NSInteger)section
{
CGFloat columnMargin = 0;
if (section == 1) {
columnMargin = 15;
}
return columnMargin;
}
/**
* 行间距
*/
- (CGFloat)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout rowMarginInSection:(NSInteger)section
{
CGFloat rowMargin = 0;
if (section == 0) {
rowMargin = 10;
} else if (section == 1) {
rowMargin = 15;
} else {
rowMargin = 10;
}
return rowMargin;
}
/**
* UIEdgeInsets
*/
- (UIEdgeInsets)waterfallFlowLayout:(DMWaterfallFlowLayout *)waterfallFlowLayout edgeInsetsInSection:(NSInteger)section
{
UIEdgeInsets sectionEdgeInsets = UIEdgeInsetsZero;
if (section == 0) {
sectionEdgeInsets = UIEdgeInsetsMake(10, 0, 10, 0);
} else if (section == 1) {
sectionEdgeInsets = UIEdgeInsetsMake(15, 15, 15, 15);
} else {
sectionEdgeInsets = UIEdgeInsetsMake(10, 0, 10, 0);
}
return sectionEdgeInsets;
}
#pragma mark - getter and setter
- (UICollectionView *)myCollectionView
{
if (_myCollectionView == nil) {
DMWaterfallFlowLayout *waterfallFlowLayout = [[DMWaterfallFlowLayout alloc] init];
waterfallFlowLayout.delegate = self;
_myCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 64, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 64) collectionViewLayout:waterfallFlowLayout];
_myCollectionView.dataSource = self;
_myCollectionView.backgroundColor = [UIColor whiteColor];
_myCollectionView.delegate = self;
[_myCollectionView registerClass:[DMSectionHeaderCollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:kDMSectionHeaderCollectionReusableViewIdentifier];
[_myCollectionView registerClass:[DMSectionFooterCollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:kDMSectionFooterCollectionReusableViewIdentifier];
[_myCollectionView registerClass:[DMNormalCollectionViewCell class] forCellWithReuseIdentifier:kDMNormalCollectionViewCellIdentifier];
[_myCollectionView registerClass:[DMWaterfallCollectionViewCell class] forCellWithReuseIdentifier:kDMWaterfallCollectionViewCellIdentifier];
}
return _myCollectionView;
}
- (NSMutableArray *)dataArray
{
if (_dataArray == nil) {
_dataArray = [[NSMutableArray alloc] init];
}
return _dataArray;
}
效果图如下
瀑布流-1.gif
瀑布流部分是第二个section,第一个section和第三个section是正常的。
网友评论