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;
}