支持多分区的动态自适应宽度layout,完善了之前只支持一个分区的布局,这里直接上代码,可以用来在商品sku, 搜索记录,编辑tab等场景的使用,灵活性强,支持代理配置
//
// LBNumberCenterEditTabLayout.m//
// Created by liubo on 26.3.25.//#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@protocol LBNumberCenterEditTabLayout.mDelegate <NSObject>- (CGSize)sizeForItemAtIndexPath:(NSIndexPath *)indexPath;- (CGSize)sizeForHeaderViewAtSection:(NSInteger)section;@end@interface LBNumberCenterEditTabLayout.m : UICollectionViewFlowLayout@property (nonatomic, weak) id <LIVNumberCenterEditTabLayoutDelegate> delegate;@property (nonatomic, assign) CGFloat contentWidth;@endNS_ASSUME_NONNULL_END
//
// LBNumberCenterEditTabLayout.m
//
//
// Created by liubo on 26.3.25.
//#import "LBNumberCenterEditTabLayout.m"@interface LBNumberCenterEditTabLayout.m ()@property (nonatomic, strong) NSMutableArray<UICollectionViewLayoutAttributes *> *layoutAttributesArray;@property (nonatomic, assign) CGSize contentSize;@end@implementation LBNumberCenterEditTabLayout.m- (instancetype)init {if (self = [super init]) {self.layoutAttributesArray = [NSMutableArray new];}return self;
}- (void)prepareLayout {[super prepareLayout];[self updateLayout];
}- (CGSize)collectionViewContentSize {return self.contentSize;
}- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {return self.layoutAttributesArray;
}#pragma mark - ---------- update ----------- (void)updateLayout {// 移除旧的布局[self.layoutAttributesArray removeAllObjects];CGFloat currentY = 0;CGFloat x = self.sectionInset.left;// 计算新的布局NSInteger sectionCount = [self.collectionView numberOfSections];for (int i = 0; i < sectionCount; i ++) {CGSize headerSize = CGSizeZero;if (self.delegate && [self.delegate respondsToSelector:@selector(sizeForHeaderViewAtSection:)]) {headerSize = [self.delegate sizeForHeaderViewAtSection:i];}if (!CGSizeEqualToSize(headerSize, CGSizeZero)) {UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader withIndexPath:[NSIndexPath indexPathForItem:0 inSection:i]];;layoutAttributes.frame = CGRectMake(0, currentY, headerSize.width, headerSize.height);currentY += headerSize.height;[self.layoutAttributesArray addObject:layoutAttributes];}NSInteger count = 0;if ([self.collectionView.dataSource respondsToSelector:@selector(collectionView:numberOfItemsInSection:)]) {count = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:0];}CGFloat currentX = x;if (count > 0) {for (int j = 0; j < count; j++) {CGSize cellSize = [self sizeForItemAtIndexPath:[NSIndexPath indexPathForItem:j inSection:i]];CGFloat cellWidth = cellSize.width;CGFloat cellHeight = cellSize.height;// 创建布局属性UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:j inSection:i]];layoutAttributes.frame = CGRectMake(currentX, currentY, cellWidth, cellHeight);[self.layoutAttributesArray addObject:layoutAttributes];currentX += (self.minimumInteritemSpacing + cellWidth);// 计算下一个item的x,以及布局更新结束检测if (j != count - 1) {if (currentX + cellWidth + self.minimumInteritemSpacing + self.sectionInset.right > self.contentWidth) {currentX = self.sectionInset.left;currentY += self.minimumLineSpacing + cellHeight;}} else {currentY += cellHeight;}if (i == sectionCount - 1 && j == count - 1) {self.contentSize = CGSizeMake(self.contentWidth, currentY);}}}}
}- (CGSize)sizeForItemAtIndexPath:(NSIndexPath *)index {CGSize size = CGSizeZero;if ([self.delegate respondsToSelector:@selector(sizeForItemAtIndexPath:)]) {size = [self.delegate sizeForItemAtIndexPath:index];}return size;
}@end