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

封装了一个iOS水平方向动态宽度layout

我们有时候会遇到这样的情形,就是需要展示一些动态的标签,宽度是动态的,
水平方向是一行,其实这种情况还是比较容易处理的,只是一下子想不起来,
这里做了一个相关的需求,将思路和代码记录下来,方便后续的查找
效果图
请添加图片描述

思路:就是重写自定义layout的prepare layout 方法, 在里面计算每一个item 的frame
。通过[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:i inSection:0]] 方法创建 UICollectionViewLayoutAttributes 对象,然后个UICollectionViewLayoutAttributes 对象的frame赋值,这里要记录上一个UICollectionViewLayoutAttributes对象的x.及总的宽度。通过这句代码赋值frame
layoutAttributes.frame = CGRectMake(currentX, currentY, cellWidth, cellHeight);
然后将布局属性添加到一个数组中
在layoutAttributesForElementsInRect:方法中返回数组。
在 collectionViewContentSize 方法中返回宽度
还有一点,我们需要通过代理方式获取到单个item的宽度

  • (CGFloat)cellWidthForItemAtIndex:(NSInteger)index;

  • (CGFloat)footerWidthForFooterAtSection:(NSInteger)section;

代码

@protocol LIUNumberCenterAssociationLayoutDelegate <NSObject>

- (CGFloat)cellWidthForItemAtIndex:(NSInteger)index;

- (CGFloat)footerWidthForFooterAtSection:(NSInteger)section;

@end

@interface LIUNumberCenterAssociationLayout : UICollectionViewFlowLayout

@property (nonatomic, weak) id <LIUNumberCenterAssociationLayoutDelegate> delegate;

@end
//
//  LIUNumberCenterAssociationLayout.m
//

#import "LIUNumberCenterAssociationLayout.h"

@interface LIUNumberCenterAssociationLayout ()

@property (nonatomic, strong) NSMutableArray<UICollectionViewLayoutAttributes *> *layoutAttributesArray;

@property (nonatomic, assign) CGSize contentSize;

@end

@implementation LIUNumberCenterAssociationLayout


- (instancetype)init {
    if (self = [super init]) {
        self.layoutAttributesArray = [NSMutableArray new];
        self.contentSize = CGSizeMake(16, 22); // 16是左边距
    }
    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];
    self.contentSize = CGSizeMake(8, 28); // 16是左边距
    // 计算新的布局
    NSInteger count = 0;
    if ([self.collectionView.dataSource respondsToSelector:@selector(collectionView:numberOfItemsInSection:)]) {
        count = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:0];
    }
    CGFloat x = 0; 

    if (count > 0) {
        for (int i = 0; i < count; i++) {
            CGFloat currentX = x;
            CGFloat currentY = 0;
            CGFloat cellWidth = [self cellWidthForItemAtIndex:i];
            CGFloat cellHeight = 28;
            // 创建布局属性
            UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
            layoutAttributes.frame = CGRectMake(currentX, currentY, cellWidth, cellHeight);
            [self.layoutAttributesArray addObject:layoutAttributes];
            // 计算下一个item的x,以及布局更新结束检测
            if (i < count - 1) {
                x = currentX + cellWidth + 8; // 8是间距
            } else {
                x = currentX + cellWidth + 8; // 8是右边距
                self.contentSize = CGSizeMake(x, 0);
            }
        }
    }
    if ([self.delegate respondsToSelector:@selector(footerWidthForFooterAtSection:)]) {
        CGFloat footerWidth = [self.delegate footerWidthForFooterAtSection:0];
        UICollectionViewLayoutAttributes *layoutattribute = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter withIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
        layoutattribute.frame = CGRectMake(x, 0, footerWidth, 28);
        x += footerWidth ;
        self.contentSize = CGSizeMake(x, 28);
        [self.layoutAttributesArray addObject:layoutattribute];
    }
}

- (CGFloat)cellWidthForItemAtIndex:(NSInteger)index {
    CGFloat width = 0;
    if ([self.delegate respondsToSelector:@selector(cellWidthForItemAtIndex:)]) {
        width = [self.delegate cellWidthForItemAtIndex:index];
    }
    return width;
}

@end


http://www.kler.cn/news/333237.html

相关文章:

  • 反调试—1
  • websockets库使用(基于Python)
  • 【AI学习】Mamba学习(二):线性注意力
  • Qt系统学习篇(6)-QMainWindow
  • 新闻推荐系统:Spring Boot的可扩展性
  • Linux:Linux进程概念
  • 前端Vue项目的自动打包、上传与部署
  • 数据结构-链表笔记
  • PostgreSQL的pglz使用限制
  • 【递归】12. leetcode 1448 统计二叉树中好节点的数目
  • CSS画出三角形的做法
  • CNI(Container Network Interface)机制是一种用于容器网络的标准化接口,旨在为容器提供一致的网络插件模型。
  • Ps:将画板导出到 PDF
  • 关于 Angular SSR 应用 html 源代码中的 ng-state script 标签
  • SQL中如何进行 ‘’撤销‘’ 操作-详解
  • HTMLCSS练习
  • 鸿蒙harmonyos next flutter通信之BasicMessageChannel获取app版本号
  • Netty:高性能异步网络编程框架全解析
  • 08.useInterval
  • 树莓派5:换源(针对Debian12)+安装包管理器Archiconda(图文教程+详细+对初学者超级友好)