IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 记一次实现自定义UICollectionViewLayout -> 正文阅读

[移动开发]记一次实现自定义UICollectionViewLayout

自定义UICollectionViewLayout 流程

一 在 prepareLayout 创建布局属性

//创建layout类,继承于系统类 UICollectionViewFlowLayout
@interface TPShareCollectionViewFlowLayout : UICollectionViewFlowLayout

@end
/// 重写 prepareLayout 方法,并在该方法里面创建布局属性
- (void)prepareLayout
{
    [super prepareLayout];
    [self configLayout];
}

/// 创建布局的方法
- (void)configLayout
{
///添加了一个 layoutAttributesArray 数组,用来持有创建的布局属性,并在 layoutAttributesForElementsInRect 返回
    [self.layoutAttributesArray removeAllObjects];
    NSInteger count = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:0];
    CGFloat left = 0;
    for (NSInteger i = 0; i < count ;i ++) {
        // 创建布局属性
        UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        /// 这里是一个自定义的代理方法,通过改方法获取到相应item的size
        CGSize size = [self.delegate collection:self.collectionView sizeForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
        CGRect frame = CGRectMake(left, 0, size.width, size.height);
        layoutAttributes.frame =  frame;
        [self.layoutAttributesArray addObject:layoutAttributes];
        if (i == count - 1) {
            self.width = left + size.width;
        } else {
            left += (size.width + self.minimumLineSpacing);
        }
    }
}

二、 重写 layoutAttributesForElementsInRect 在里面返回创建的布局属性数组

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    return self.layoutAttributesArray;
}

三、 重写 collectionViewContentSize方法,并在里面返回总内容的size

注意,我们需要在自定义layout 中管理记录当前布局的size,用来返回,因为我这里高度是固定的,所以自己记录的内容的宽度
即self.width 这个自定义属性

- (CGSize)collectionViewContentSize
{
    return CGSizeMake(self.width, self.collectionView.bounds.size.height);
}

注意点

一、我们自定义layout 布局在创建属性布局的时候需要记录一个当前的origin

因为我这里自定义的y是固定的,都是0(一个横向的自定义layout),所以只是维护记录了一个当前的x位置
即left

  left += (size.width + self.minimumLineSpacing);

二、 如果我们自定义的layout 重写prepareLayout,则我们必须重写collectionViewContentSize 方法

**collectionViewContentSize 默认会根据系统的布局属性数组(我们不知道属性名字)layout. 自身的总size **

不重写collectionViewContentSize 方法的话,layout 还是使用系统的数组来决定size, 因为我们重写了prepareLayout 方法,所以系统的数组并没有创建,这样就无法返回正确的size了,所以我们需要自己在创建布局属性的时候记录一下当前的size,因为我这里高度是固定的,所以只记录宽度就可以了

 if (i == count - 1) {
      self.width = left + size.width;
   }
- (CGSize)collectionViewContentSize
{
    return CGSizeMake(self.width, self.collectionView.bounds.size.height);
}

三 、 自定义layout 中系统不支持直接获取某个item的size ,需要我们自定义协议并设置代理获取

@protocol TPShareCollectionViewFlowLayoutProtocol <NSObject>

- (CGSize)collection:(UICollectionView *)collectionView sizeForItemAtIndexPath:(NSIndexPath *)indexPath;

@end

     UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        CGSize size = [self.delegate collection:self.collectionView sizeForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
        CGRect frame = CGRectMake(left, 0, size.width, size.height);

四、 总结起来就是 : 每个item frame 的origin 需要layout 自己记录维护,size 需要通过代理获取

完整代码

.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@protocol TPShareCollectionViewFlowLayoutProtocol <NSObject>

- (CGSize)collection:(UICollectionView *)collectionView sizeForItemAtIndexPath:(NSIndexPath *)indexPath;

@end

@interface TPShareCollectionViewFlowLayout : UICollectionViewFlowLayout

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

@end

NS_ASSUME_NONNULL_END

.m

#import "TPShareCollectionViewFlowLayout.h"

@interface TPShareCollectionViewFlowLayout ()

@property (nonatomic, assign) CGFloat width;

@property (nonatomic, strong) NSMutableArray *layoutAttributesArray;

@end

@implementation TPShareCollectionViewFlowLayout

- (void)prepareLayout
{
    [super prepareLayout];
    [self configLayout];
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    return self.layoutAttributesArray;
}

- (void)configLayout
{
    [self.layoutAttributesArray removeAllObjects];
    NSInteger count = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:0];
    CGFloat left = 0;
    for (NSInteger i = 0; i < count ;i ++) {
        // 创建布局属性
        UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        CGSize size = [self.delegate collection:self.collectionView sizeForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
        CGRect frame = CGRectMake(left, 0, size.width, size.height);
        layoutAttributes.frame =  frame;
        [self.layoutAttributesArray addObject:layoutAttributes];
        if (i == count - 1) {
            self.width = left + size.width;
        } else {
            left += (size.width + self.minimumLineSpacing);
        }
    }
}

- (CGSize)collectionViewContentSize
{
    return CGSizeMake(self.width, self.collectionView.bounds.size.height);
}

- (NSMutableArray *)layoutAttributesArray
{
    if (!_layoutAttributesArray) {
        _layoutAttributesArray = [NSMutableArray array];
    }
    return _layoutAttributesArray;
}

@end

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-29 12:16:33  更:2022-04-29 12:17:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 23:48:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码