iOS ------ UICollectionView

news2024/9/29 19:21:16

一,UICollectionView的简介
UICollectionView是iOS6之后引入的一个新的UI控件,它和UITableView有着诸多的相似之处,其中许多代理方法都十分类似。简单来说,UICollectionView是比UITbleView更加强大的一个UI控件,有如下几个方面:

1.支持水平和垂直两种方向的布局
2.通过layout配置方式进行布局
3.类似于TableView的cell特性外,collectionView中的item大小和位置可以自由定义;
4.通过layout布局回调的代理方法,可以动态的定制每个item的大小和collection的大体布局属性
5.更加强大一点,完全自定义一套layout布局方案,可以实现意想不到的效果。

设置静态的布局

实现一个最简单的九宫格类布局

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //创建一个layout布局类
    UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]  init];
    flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
    //flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    //flowLayout.itemSize = CGSizeMake((self.view.frame.size.width - 80) / 3, (self.view.frame.size.width - 80) / 3);
    //flowLayout.itemSize = CGSizeMake(100, 100 );
    //flowLayout.minimumLineSpacing = 20;
    //flowLayout.minimumInteritemSpacing = 20;
    flowLayout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
    //创建collectionView,通过一个布局策略layout来创建
    self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:flowLayout];
    //注册cell
    [self.collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
    //设置代理
    self.collectionView.delegate = self;
    //设置数据源
    self.collectionView.dataSource = self;
    [self.view addSubview:self.collectionView];
}

这里有一点需要注意,collectionView在完成代理回调前,必须注册一个cell,类似如下:

//注册cell
    [self.collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"cell"];

这和tableView有些类似,又有些不同,因为tableView除了注册cell的方法外,还可以通过非注册的方法,当复用池中没有可用的cell时,可以返回nil,然后重新创建。

//tableView在从复用池中取cell的时候,有如下两种方法
//使用这种方式如果复用池中无,是可以返回nil的,我们在临时创建即可
- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;
//6.0后使用如下的方法直接从注册的cell类获取创建,如果没有注册 会崩溃
- (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);

因为UICollectionView是iOS6.0之前的新类,因此这里统一了从复用池中获取cell的方法,没有再提供可以返回nil的方式,并且在UICollectionView的回调代理中,只能使用从复用池中获取cell的方式进行cell的返回,其他方式会崩溃。

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor colorWithRed:arc4random() % 255 / 255.0 green:arc4random() % 255 / 255.0 blue:arc4random() % 255 / 255.0 alpha:1];
    return cell;
}

然后实现其他的代理方法

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return 9;
}

在这里插入图片描述
上面我们写了一个简单九宫格的代码,所有的item都是一样大小的,但是有时候这样满足不了我们的需求,我们有时候可能也需要item不同大小。
在上面代码的基础上,删除控制item的大小的代码,再加入下面几行代码即可实现:

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    if (indexPath.row % 2 == 0) {
        return CGSizeMake(50, 50);
    } else {
        return CGSizeMake(80, 80);
    }
}

在这里插入图片描述

设置动态布局

自定义FlowLayout进行瀑布流布局
首先,我们新建一个文件继承于UICollectionViewFlowLayout:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyLayout : UICollectionViewFlowLayout
@property (nonatomic, assign)int itemCount;
@end

NS_ASSUME_NONNULL_END

前面说过,UICollectionViewFlowLayout是一个专门用来管理collectionView布局的类,因此,collectionView在进行UI布局前,会通过这个类的对象获取相关的布局信息,FlowLayout类将这些布局信息全部存放在了一个数组中,数组中是UICollectionViewLayoutAttributes类,这个类是对item布局的具体设置,以后咱们在讨论这个类。总之,**FlowLayout类将每个item的位置等布局信息放在一个数组中,在collectionView布局时,会调用FlowLayout类layoutAttributesForElementsInRect:方法来获取这个布局配置数组。因此,我们需要重写这个方法,返回我们自定义的配置数组,**另外,FlowLayout类在进行布局之前,会调用prepareLayout方法,所以我们可以重写这个方法,在里面对我们的自定义配置数据进行一些设置。

简单来说,自定义一个FlowLayout布局类就是两个步骤:

1、设计好我们的布局配置数据 prepareLayout方法中

2、返回我们的配置数组 layoutAttributesForElementsInRect方法中

#import "MyLayout.h"

@implementation MyLayout {
    NSMutableArray* attributeArray;
}
- (void)prepareLayout {
    attributeArray = [[NSMutableArray alloc] init];
    [super prepareLayout];
    float WIDTH = ([UIScreen mainScreen].bounds.size.width - self.sectionInset.left - self.sectionInset.right - self.minimumInteritemSpacing) / 2;
    
    CGFloat colHeight[2] = {self.sectionInset.top, self.sectionInset.bottom};
    
    for(int i = 0; i < self.itemCount; i++) {
        NSIndexPath* index = [NSIndexPath indexPathForItem:i inSection:0];
        
        UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:index];
        CGFloat height = arc4random() % 150 + 40;
        int width = 0;
        if (colHeight[0] < colHeight[1]) {
            colHeight[0] = colHeight[0] + height + self.minimumLineSpacing;
            width = 0;
        } else {
            colHeight[1] = colHeight[1] + height + self.minimumLineSpacing;
            width = 1;
        }
        attributes.frame = CGRectMake(self.sectionInset.left + (self.minimumInteritemSpacing + WIDTH) * width, colHeight[width] - height - self.minimumLineSpacing, WIDTH, height);
        [attributeArray addObject:attributes];
    }
    if (colHeight[0] > colHeight[1]) {
        self.itemSize = CGSizeMake(WIDTH, (colHeight[0] - self.sectionInset.top) * 2 / self.itemCount - self.minimumLineSpacing);
    } else {
        self.itemSize = CGSizeMake(WIDTH, (colHeight[1] - self.sectionInset.top) * 2 / self.itemCount - self.minimumLineSpacing);
    }
}
- (NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
    return attributeArray;
}
@end

自定义完成FlowLayout后,在View Controller中使用

#import "ViewController.h"
#import "MyLayout.h"
#import "CollectionViewCell.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    MyLayout* layout = [[MyLayout alloc] init];
    layout.scrollDirection = UICollectionViewScrollDirectionVertical;
    layout.itemCount = 100;
    UICollectionView* collectView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
    collectView.delegate = self;
    collectView.dataSource = self;
    
    [collectView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
    [self.view addSubview:collectView];
    // Do any additional setup after loading the view.
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return 100;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor colorWithRed:arc4random() % 255 / 255.0 green:arc4random() % 255 / 255.0 blue:arc4random() % 255 / 255.0 alpha:1];
    return cell;
}
@end

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1283663.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言中如何取一串比特中的特定位的比特

#include <iostream> #include <bitset> using namespace std; /* 向右的移位操作相当于丢掉最后的几位&#xff0c;然后剩下的位数进行“与”运算即可。 */ int main() {int a 0x2FB7; //0x2FB70010 1111 1011 0111char end3 (a >> 4) & 0x07; //取a…

Javaweb之Vue路由的详细解析

5 Vue路由 5.1 路由介绍 将资代码/vue-project(路由)/vue-project/src/views/tlias/DeptView.vue拷贝到我们当前EmpView.vue同级&#xff0c;其结构如下&#xff1a; 此时我们希望基于4.4案例中的功能&#xff0c;实现点击侧边栏的部门管理&#xff0c;显示部门管理的信息&am…

“影响力”经济:抖音为什么更值得商家、达人长期深耕?

文&#xff5c;新熔财经 作者&#xff5c;叶一城 数亿的活跃用户&#xff0c;简单而自然的切入方式&#xff0c;快速、高频的执行效率&#xff0c;让抖音对电商界的冲击无可阻挡。 这背后&#xff0c;流量玩法登峰造极&#xff0c;是很多人的直接观感。 但实际上&#xff0…

FL Studio 21.2.1.3859中文破解版及FL Studio怎么录制

FL Studio 21.2.1.3859中文破解版是一个数字音频工作站 (DAW)。该软件借助各种编辑工具、插件和效果&#xff0c;让您可以录制、混音和掌握高度复杂的音乐作品。FL Studio 21还允许您注册和编辑 MIDI 文件&#xff0c;您可以在众多可用乐器之一上演奏这些文件。FL Studio 拥有 …

【VRTK】【VR开发】【Unity】10-连续移动

课程配套学习资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【概述】 连续移动与瞬移有如下不同: 连续移动不容易打断沉浸对于新手或者不适应者来说更容易晕动 我对玩家的建议:连续移动前后左右可以用摇杆,转向用自己…

java常用知识点记忆

类的继承与多态 类的继承不支持多重继承非private 方法才可以被覆盖覆盖的方法要求&#xff0c;子类中的方法的名字&#xff0c;参数列表&#xff0c;返回类型与父类相同方法的重载是在一个类中定义方法名字相同&#xff0c;但是参数列表不同的方法要是在子类中定义了与父类名字…

Huawei FusionSphere FusionCompte FusionManager

什么是FusionSphere FusionSphere 解决方案不独立发布软件&#xff0c;由各配套部件发布&#xff0c;请参 《FusionSphere_V100R005C10U1_版本配套表_01》。 目前我们主要讨论FusionManager和FusionCompute两个组件。 什么是FusionCompte FusionCompute是华为提供的虚拟化软…

深度学习训练 tricks(持续更新)

妈妈&#xff0c;我的炼丹炉子炸啦&#xff08;不是&#xff09; 妈妈&#xff0c;我的深度学习模型训练好了&#xff01; 本文持续更新&#xff0c;如果有什么你知道的深度学习模型训练技巧&#xff0c;可以在评论区提出&#xff0c;我会加进来的。 文章目录 weight decaywe…

3DMM模型

目录 BFMBFM_200901_MorphableModel.matexp_pca.bintopology_info.npyexp_info.npy BFM BFM_2009 01_MorphableModel.mat from scipy.io import loadmat original_BFM loadmat("01_MorphableModel.mat") # dict_keys: [__header__, __version__, __globals__, # …

C++ 文件操作之配置文件读取

C 文件操作之配置文件读取 在项目应用时常常会涉及一些调参工作&#xff0c;如果项目封装成了.exe或者.dll&#xff0c;那么频繁调参多次编译是一件十分低效的事情&#xff0c;如果代码算法或者逻辑是一定的&#xff0c;那么参数完全可以通过读入配置文件来获取之前在用C - op…

SpringBoot药品进销存管理系统(诊所管理系统)(乡村药店管理系统)

SSM毕设分享 SpringBoot药品进销存管理系统(诊所管理系统)(乡村药店管理系统) 1 项目简介 Hi&#xff0c;各位同学好&#xff0c;这里是郑师兄&#xff01; 今天向大家分享一个毕业设计项目作品【SpringBoot药品进销存管理系统(诊所管理系统)(乡村药店管理系统)】 师兄根据实…

ROS-ROS通信机制-话题通信

文章目录 一、话题通信基础知识二、话题通信基本操作2-1 C2-2 Python2-3 C与python节点通信 三、自定义msg3-1 自定义msg3-2 C实现自定义msg调用3-3 Python实现自定义msg调用 一、话题通信基础知识 话题通信实现模型是比较复杂的&#xff0c;该模型如下图所示,该模型中涉及到三…

zxjy001-项目整体介绍

1、项目类型 全栈项目 前端&#xff1a;系统后台&#xff0c;系统前台后端&#xff1a;提供API接口 2、项目技术栈 前端 Vue,Element,Axios,NodeJs后端 Spring Boot,Spring Cloud,MybatisPlus,Spring Security,Redis,Maven,JWT,OAuth2其他技术 阿里云oss服务阿里云视频点播…

微服务实战系列之Cache(技巧篇)

前言 凡工具必带使用说明书&#xff0c;如不合理的使用&#xff0c;可能得到“意外收获”。这就好比每个人擅长的领域有所差异&#xff0c;如果放错了位置或用错了人&#xff0c;也一定会让 Leader 们陷入两难之地&#xff1a;“上无法肩负领导之重托&#xff0c;下难免失去伙伴…

设计模式之代理模式(1)

目录 概述定义应用场景主要角色类图 详述基本代码应用实例符合的设计原则 总结 概述 定义 代理模式是一种结构型设计模式&#xff0c;它允许通过一个代理对象来控制对原始对象的访问。代理对象可以在不改变原始对象的情况下&#xff0c;增加一些额外的功能&#xff0c;例如权限…

kubectl获取ConfigMap导出YAML时如何忽略某些字段

前言&#xff1a; 当我们在使用Kubernetes时&#xff0c;常常需要通过kubectl命令行工具来管理资源。有时我们也想将某个资源的配置导出为YAML文件&#xff0c;这样做有助于版本控制和资源的迁移。然而&#xff0c;默认情况下&#xff0c;使用kubectl get命令导出资源配置会包…

【IPv6】IPv6协议

一、IPv6数据报格式 这是与v4报头的对比 1.8bit的版本保留了&#xff0c;v4版本就是4&#xff0c;v6就是6。 2.v6去除了v4的首部长度字段&#xff0c;因为v6的首部长是固定的40字节。 3.服务类型&#xff08;Type of Service, ToS&#xff09;和通信类型&#xff08;Traffi…

【Linux下如何生成coredump文件】

一&#xff0c;什么是coredump 我们经常听到大家说到程序core掉了&#xff0c;需要定位解决&#xff0c;这里说的大部分是指对应程序由于各种异常或者bug导致在运行过程中异常退出或者中止&#xff0c;并且在满足一定条件下&#xff08;这里为什么说需要满足一定的条件呢&#…

贝叶斯网络 (人工智能期末复习)

文章目录 贝叶斯网络&#xff08;概率图模型&#xff09;定义主要考点例题- 要求画出贝叶斯网络图- 计算各节点的条件概率表- 计算概率- 分析独立性 贝叶斯网络&#xff08;概率图模型&#xff09; 定义 一种简单的用于表示变量之间条件独立性的有向无环图&#xff08;DAG&am…

操作系统概述及发展史、Linux内核、发行版及应用领域

一、 操作系统&#xff08;Operation System&#xff0c;OS&#xff09; 裸机&#xff1a;没有安装操作系统的计算机 如果想在 裸机 上运行自己所编写的程序&#xff0c;就必须用机器语言书写程序如果计算机上安装了操作系统&#xff0c;就可以在操作系统上安装支持的高级语言…