1.绘制瀑布流的时候,如果没有对Layout做特殊处理,会导致header的代理方法不执行
分析原因:重写布局的时候(prepareLayout此方法),只对cell布局进行的处理,而没有加入header的布局属性
解决办法:重写布局的时候(prepareLayout此方法)加上header的布局
2.贴上代码
.h文件
@interface ZTYWaterflowLayout : UICollectionViewFlowLayout
- (instancetype)initRowMargin:(CGFloat)rowMargin SectionMargin:(CGFloat)sectionMargin rowCount:(NSInteger)rowCount colInsets:(UIEdgeInsets)colInsets fixCellH:(NSInteger)cellHeight;
@end
.m文件
/** 默认的列数 */
static const NSInteger CXDDefaultColumnCount = 2;
/** 每一列之间的间距 */
static const CGFloat CXDDefaultColumnMargin = 7;
/** 每一行之间的间距 */
static const CGFloat CXDDefaultRowMargin = 7;
/** 边缘间距 */
static const UIEdgeInsets CXDDefaultEdgeInsets = {0, 12, 0, 12};
@interface ZTYWaterflowLayout ()
/** 存放所有cell的布局属性 */
@property (nonatomic, strong) NSMutableArray *attrsArray;
/** 存放所有列的当前高度 */
@property (nonatomic, strong) NSMutableArray *columnHeights;
@property (assign,nonatomic) CGFloat rowMargin;
@property (assign,nonatomic) CGFloat sectionMargin;
@property (assign,nonatomic) NSInteger rowCount;
@property (assign,nonatomic) UIEdgeInsets colInsets;
@property (assign,nonatomic) CGFloat cellHeight;
@end
@implementation ZTYWaterflowLayout
- (NSMutableArray *)columnHeights
{
if (!_columnHeights) {
_columnHeights = [NSMutableArray array];
}
return _columnHeights;
}
- (NSMutableArray *)attrsArray
{
if (!_attrsArray) {
_attrsArray = [NSMutableArray array];
}
return _attrsArray;
}
- (instancetype)initRowMargin:(CGFloat)rowMargin SectionMargin:(CGFloat)sectionMargin rowCount:(NSInteger)rowCount colInsets:(UIEdgeInsets)colInsets fixCellH:(NSInteger)cellHeight
{
self = [super init];
if (self) {
_rowMargin = rowMargin;
_sectionMargin = sectionMargin;
_rowCount = rowCount;
_colInsets = colInsets;
_cellHeight = cellHeight;
}
return self;
}
- (instancetype)init
{
self = [super init];
if (self) {
_rowMargin = CXDDefaultRowMargin;
_sectionMargin = CXDDefaultColumnMargin;
_rowCount = CXDDefaultColumnCount;
_colInsets = CXDDefaultEdgeInsets;
}
return self;
}
/**
* 初始化
*/
- (void)prepareLayout
{
[super prepareLayout];
// 清除以前计算的所有高度
[self.columnHeights removeAllObjects];
for (NSInteger i = 0; i < _rowCount; i++) {
[self.columnHeights addObject:@(_colInsets.top+self.headerReferenceSize.height)]; // 注意别忘了把header的高度也加上
}
// 清除之前所有的布局属性
[self.attrsArray removeAllObjects];
//头部视图 加入header布局属性
UICollectionViewLayoutAttributes * layoutHeader = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader withIndexPath:[NSIndexPath indexPathWithIndex:0]];
layoutHeader.frame =CGRectMake(0,0, self.headerReferenceSize.width, self.headerReferenceSize.height);
[self.attrsArray addObject:layoutHeader];
// 开始创建每一个cell对应的布局属性
NSInteger count = [self.collectionView numberOfItemsInSection:0];
for (NSInteger i = 0; i < count; i++) {
// 创建位置
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
// 获取indexPath位置cell对应的布局属性
UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
[self.attrsArray addObject:attrs];
}
}
/**
* 决定cell的排布
*/
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
return self.attrsArray;
}
/**
* 返回indexPath位置cell对应的布局属性
*/
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
// 创建布局属性
UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
// collectionView的宽度
CGFloat collectionViewW = self.collectionView.frame.size.width;
// 设置布局属性的frame
CGFloat w = (collectionViewW - _colInsets.left - _colInsets.right - (_rowCount - 1) * _sectionMargin) / _rowCount;
CGFloat h = 50 + arc4random_uniform(100);
if (indexPath.row % 2 == 1) {
h = 285;
}else{
h = 307;
}
if (_cellHeight > 0) {
h = _cellHeight;
}
// 找出高度最短的那一列
NSInteger destColumn = 0;
CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];
for (NSInteger i = 1; i < _rowCount; i++) {
// 取得第i列的高度
CGFloat columnHeight = [self.columnHeights[i] doubleValue];
if (minColumnHeight > columnHeight) {
minColumnHeight = columnHeight;
destColumn = i;
}
}
CGFloat x = _colInsets.left + destColumn * (w + _sectionMargin);
CGFloat y = minColumnHeight ;
if (y != _colInsets.top) {
y += _rowMargin;
}
attrs.frame = CGRectMake(x, y , w, h);
// 更新最短那列的高度
self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));
return attrs;
}
- (CGSize)collectionViewContentSize
{
CGFloat maxColumnHeight = [self.columnHeights[0] doubleValue];
for (NSInteger i = 1; i < _rowCount; i++) {
// 取得第i列的高度
CGFloat columnHeight = [self.columnHeights[i] doubleValue];
if (maxColumnHeight < columnHeight) {
maxColumnHeight = columnHeight;
}
}
return CGSizeMake(0, maxColumnHeight + _colInsets.bottom);
}
@end
3.使用
ZTYWaterflowLayout * layout = [[ZTYWaterflowLayout alloc] init];
layout.headerReferenceSize = CGSizeMake(kSCREEN_WIDTH, 200); // 设置header的尺寸
ZTYCollectionView * collview = [[ZTYCollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
collview.delegate = self;
collview.dataSource = self;
[self.view addSubview:collview];
[collview registerClass:[GoodsCollectionCell class] forCellWithReuseIdentifier:@"goodscell"];
[collview registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header"];
// 代理方法
-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
UICollectionReusableView * reusaview = nil;
if (kind == UICollectionElementKindSectionHeader) {
reusaview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"pageHead" forIndexPath:indexPath];
UIView * headview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)];
[reusaview addSubview:headview];
}
return reusaview;
}