//
// PGGridLayout.m
// TestCollectionView
//
// Created by Yang Li on 2018/12/5.
// Copyright © 2018 Qiekj. All rights reserved.
//
#import "PGGridLayout.h"
@interface PGGridLayout ()
@property(nonatomic, strong)NSArray *layoutInfoArray;
@property(nonatomic, assign)CGSize contentSize;
@end
@implementation PGGridLayout
- (instancetype)init {
if (self = [super init]) {
self.cellSpacing = 10;
self.lineSpacing = 10;
self.itemSize = CGSizeMake(100, 100);
}
return self;
}
- (void)setItemSize:(CGSize)itemSize {
_itemSize = itemSize;
[self invalidateLayout];
}
- (void)setLineSpacing:(CGFloat)lineSpacing {
_lineSpacing = lineSpacing;
[self invalidateLayout];
}
- (void)setCellSpacing:(CGFloat)cellSpacing {
_cellSpacing = cellSpacing;
[self invalidateLayout];
}
/**
prepareLayout是专门用来准备布局的,
在 prepareLayout 方法里面我们可以事先就计算后面要用到的布局信息并存储起来,
防止后面方法多次计算,提高性能。例如,我们可以在此方法就计算好每个cell的属性、整个CollectionView的内容尺寸等等。
此方法在布局之前会调用一次,之后只有在调用 invalidateLayout 、 shouldInvalidateLayoutForBoundsChange:
返回 YES 和 UICollectionView刷新 的时候才会调用。
*/
- (void)prepareLayout {
[super prepareLayout];
NSMutableArray *layoutInfoArr = [NSMutableArray array];
NSInteger maxNumberOfItems = 0;
//获取布局信息
NSInteger numberOfSections = [self.collectionView numberOfSections];
for (NSInteger section = 0; section < numberOfSections; section++){
NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:section];
NSMutableArray *subArr = [NSMutableArray arrayWithCapacity:numberOfItems];
for (NSInteger item = 0; item < numberOfItems; item++){
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];
[subArr addObject:attributes];
}
if(maxNumberOfItems < numberOfItems){
maxNumberOfItems = numberOfItems;
}
//添加到二维数组
[layoutInfoArr addObject:[subArr copy]];
}
//存储布局信息
self.layoutInfoArray = [layoutInfoArr copy];
//保存内容尺寸
self.contentSize = CGSizeMake(
self.contentInset.left + self.contentInset.right + maxNumberOfItems * (self.itemSize.width + self.cellSpacing) + self.cellSpacing,
self.contentInset.top + self.contentInset.bottom + numberOfSections * (self.itemSize.height + self.lineSpacing) + self.lineSpacing
);
}
- (CGSize)collectionViewContentSize {
return self.contentSize;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
NSMutableArray *layoutAttributesArr = [NSMutableArray array];
[self.layoutInfoArray enumerateObjectsUsingBlock:^(NSArray *array, NSUInteger i, BOOL * _Nonnull stop) {
[array enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *obj, NSUInteger idx, BOOL * _Nonnull stop) {
if(CGRectIntersectsRect(obj.frame, rect)) {
[layoutAttributesArr addObject:obj];
}
}];
}];
return layoutAttributesArr;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
//每一组cell为一行
attributes.frame = CGRectMake(
self.contentInset.left + (self.itemSize.width + self.cellSpacing) * indexPath.row + self.cellSpacing,
self.contentInset.top + (self.itemSize.height + self.lineSpacing) * indexPath.section + self.lineSpacing,
self.itemSize.width,
self.itemSize.height
);
return attributes;
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return YES;
}
@end
//
// PGGridLayout.h
// TestCollectionView
//
// Created by Yang Li on 2018/12/5.
// Copyright © 2018 Qiekj. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface PGGridLayout : UICollectionViewLayout
//每个cell 大小
@property(nonatomic, assign)CGSize itemSize;
//每个cell 间的距离
@property(nonatomic, assign)CGFloat cellSpacing;
//一行间距
@property(nonatomic, assign)CGFloat lineSpacing;
//内边距
@property(nonatomic, assign)UIEdgeInsets contentInset;
@end
NS_ASSUME_NONNULL_END
网友评论