当前位置: 首页 > news >正文

封装了一个支持多个分区的iOS自适应动态宽度layout

支持多分区的动态自适应宽度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;

@end

NS_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


相关文章:

  • 探索MVC、MVP、MVVM和DDD架构在不同编程语言中的实现差异
  • 自然语言处理|人工智能如何革新作文批改:技术全解析
  • PyTorch 深度学习实战(27):扩散模型(Diffusion Models)与图像生成
  • LearnOpenGL(九)自定义转换类
  • 在 Ubuntu 上安装 Docker 的完整指南
  • 核心:一多开发项目搭建
  • 链表(1)
  • 浅谈Binder的个人理解
  • windows第十八章 菜单、工具栏、状态栏
  • 单元测试之Arrange-Act-Assert(简称AAA)
  • 【空间变换】欧拉角与四元数
  • UE5.5_Mass框架——UE的ECS框架
  • 智慧城市智慧调度系统的架构与关键技术研究
  • 算法基础_基础算法【快速排序 + 归并排序 + 二分查找】
  • 做的一些实验
  • 记录一次TDSQL事务太大拆过binlog阈值报错
  • C语言中栈和堆详解及区别
  • MySQL General Log
  • Ubuntu 22.04.5 LTS 设置时间同步 ntp
  • Android打aar包问题总结
  • 透视社会组织创新实践中的花开岭现象:与乡村发展的融合共进
  • 美国调整对华加征关税
  • 4月新增社融1.16万亿,还原地方债务置换影响后信贷增速超过8%
  • 前四个月社会融资规模增量累计为16.34万亿元,比上年同期多3.61万亿元
  • 科技部等七部门:优先支持取得关键核心技术突破的科技型企业上市融资
  • 中国海警舰艇编队5月14日在我钓鱼岛领海巡航