iOS自定义collectionViewLayout
2020-09-09 本文已影响0人
bugLife丶
iOS自定义collectionViewLayout
iOS开发collectionView也算用的比较广泛了,但是系统的collectionViewLayout有时候不能够满足开发需求,比如小红书那种瀑布流。这里讲一讲自定义collectionViewLayout,需要重写四个方法
- -(void)prepareLayout
2.-(CGSize)collectionViewContentSize;
3.-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;
4.-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
直接上代码
@interface SSCollectionViewLayout()
/** cell height arrays */
@property(nonatomic,strong)NSArray *cellHeightArrays;
/** attributes arrays */
@property(nonatomic,strong)NSMutableArray *attributesArrays;
/** cell array */
@property(nonatomic,strong)NSMutableArray *tempAttributesArrays;
@end
@implementation SSCollectionViewLayout
-(instancetype)initWithArrays:(NSArray *)cellHeightArrays
{
if (self = [super init]) {
self.cellHeightArrays = cellHeightArrays;
}
return self;
}
//自定义layout需要重写这些方法
-(void)prepareLayout
{
[super prepareLayout];
[self.attributesArrays removeAllObjects];
[self.tempAttributesArrays removeAllObjects];
//获取当前collectionView对应区的item
//获取senction全部个数
NSInteger count = [self.collectionView numberOfItemsInSection:0];
for (int i=0; i < count; i++) {
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow: i inSection:0]];
[self.attributesArrays addObject:attributes];
}
}
//返回collectionView的内容的尺寸
-(CGSize)collectionViewContentSize
{
CGFloat maxContentHeight = CGRectGetMaxY([[self.tempAttributesArrays firstObject] frame]);
for (UICollectionViewLayoutAttributes *attributes in self.tempAttributesArrays) {
if (maxContentHeight < attributes.frame.size.height) {
maxContentHeight = CGRectGetMaxY(attributes.frame);
}
}
return CGSizeMake(self.collectionView.bounds.size.width, maxContentHeight);
}
-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
return self.attributesArrays;
}
///返回对应于indexPath的位置的cell的布局属性,返回指定indexPath的item的布局信息。子类必须重载该方法,该方法只能为cell提供布局信息,不能为补充视图和装饰视图提供。
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
CGFloat itemWidth = (self.collectionView.bounds.size.width - (10 + 10 + 10 * 2))/3;
CGFloat itemHeight = [self.cellHeightArrays[indexPath.row] floatValue];
//在这里用上cellArrays了,横排最多显示3个
if (self.tempAttributesArrays.count < 3) {//设置第一排rect
[self.tempAttributesArrays addObject:attributes];
NSLog(@"%ld",self.tempAttributesArrays.count);
CGRect rect = CGRectMake(10 +( itemWidth + 10) * (self.tempAttributesArrays.count - 1), 10, itemWidth, itemHeight);
attributes.frame = rect;
}else{
UICollectionViewLayoutAttributes *fristAttributes = [self.tempAttributesArrays firstObject];
CGFloat minY = CGRectGetMaxY(fristAttributes.frame);
CGFloat Y = minY;
NSInteger index = 0;
CGRect itemFrame = CGRectMake(fristAttributes.frame.origin.x, CGRectGetMaxY(fristAttributes.frame) + 10, itemWidth, itemHeight);
for (UICollectionViewLayoutAttributes *attri in self.tempAttributesArrays) {
if (minY > CGRectGetMaxY(attri.frame)) {
minY = CGRectGetMaxY(attri.frame);
Y = minY;
itemFrame = CGRectMake(attri.frame.origin.x, Y + 10, itemWidth, itemHeight);
NSInteger currentIndex = [self.tempAttributesArrays indexOfObject:attri];
index = currentIndex;
}
}
attributes.frame = itemFrame;
[self.tempAttributesArrays replaceObjectAtIndex:index withObject:attributes];
}
return attributes;
}
这里我们就实现了一个自定义layout,例子显示横屏3个item,高度通过动态传过来,实际开发中,需要跟后台商量,返回cell高度。