【iOS】UI学习——cell的复用及自定义cell
目录
- 前言
- cell的复用
- 手动(非注册)
- 自动(注册)
- 自定义cell
- 总结
前言
Cell复用和自定义Cell是在开发iOS应用时常见的一种优化技巧和定制需求。
Cell复用是UITableView或UICollectionView的一个重要优化机制。当用户滚动这些视图时,只有少量可见的Cell会被实际创建和显示,对于那些暂时不可见的Cell,系统会将它们缓存起来以备将来复用。这个机制主要是为了提高应用的性能,因为创建和销毁视图都是相对高开销的操作,通过复用Cell,我们可以避免不必要的视图创建和销毁,从而提高应用的滚动性能。
自定义Cell可以让你更好地控制Cell的外观和行为,提高代码的可读性和可维护性。自定义Cell主要的步骤包括创建自定义Cell类,添加UI元素,实现初始化方法,设置Cell的布局,以及在TableView中使用自定义Cell。
在实际开发中,我们通常会结合使用Cell复用和自定义Cell,以达到既优化性能又满足特定需求的目的。
cell的复用
Cell的复用是一种优化技术,主要用于iOS的UITableView和UICollectionView。需要注意的是,虽然这两种视图的实现方式略有不同,但复用的基本思想是相同的。
当用户滚动UITableView或UICollectionView时,屏幕上显示的cell只是所有数据的一小部分。当某个cell滚动出屏幕时,系统会将其放入一个队列中等待复用,而不是立即销毁。当需要显示新的cell时,系统首先会检查这个队列,看看是否有可以复用的cell。如果有,就直接使用,如果没有,才会创建新的cell。
这种复用机制可以极大地提高应用的性能。因为创建和销毁视图是相对耗费资源的操作,通过复用,可以减少这些操作,从而使滚动更加流畅。
在实现cell复用时,需要给cell设定一个复用标识符(reuse identifier),然后在需要新的cell时,使用这个标识符去请求。如果队列中有可复用的cell,系统就会返回一个,否则就会创建新的cell。标识符的设定,使得我们可以为不同类型的cell设定不同的复用标识符,从而在同一个表视图或集合视图中使用多种类型的cell。
手动(非注册)
手动进行Cell复用主要涉及到以下几个步骤:
- 设置复用标识符:在创建Cell的时候,我们需要给每个Cell设置一个复用标识符,这个标识符通常是一个字符串,用来表示这个Cell的类型。在创建Cell的时候,我们会把这个标识符作为参数传入。
- 请求重用的Cell:在需要显示新的Cell时,我们会使用复用标识符去请求一个已经不再显示,但是还没有被销毁的Cell。这个请求的过程是通过调用UITableView或UICollectionView的dequeueReusableCell(withIdentifier:)方法来完成的,这个方法会返回一个可选类型的Cell,如果有可用的重用Cell,就会返回一个Cell,否则返回nil。
- 配置Cell:无论是新创建的Cell还是重用的Cell,都需要进行配置,以显示新的数据。配置Cell通常会在tableView(:cellForRowAt:)或collectionView(:cellForItemAt:)方法中完成。
代码示例:
1. (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {static NSString *strID = @"id";UITableViewCell *cell = [_tabView dequeueReusableCellWithIdentifier: strID];if (cell == nil) {cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: strID];}cell.textLabel.text = @"aaa";return cell;
}
自动(注册)
在iOS开发中,TableView和CollectionView的Cell复用是自动完成的,你只需要正确地设置复用标识符并在需要时请求复用的Cell。具体步骤如下:
- 设置复用标识符:当你创建自定义Cell的时候,需要为每一个Cell类型设置一个唯一的复用标识符。你可以在Cell的初始化方法中或者在Storyboard中设置这个标识符。
- 请求重用的Cell:在tableView(:cellForRowAt:)或collectionView(:cellForItemAt:)方法中,你需要使用复用标识符来请求一个可复用的Cell。你可以使用dequeueReusableCell(withIdentifier:)方法来完成这个请求。如果有可复用的Cell,这个方法会返回一个Cell,否则返回nil。
- 创建新的Cell:如果dequeueReusableCell(withIdentifier:)方法返回nil,说明没有可复用的Cell,你需要创建一个新的Cell。
- 配置Cell:对于获得的Cell,无论是新创建的还是复用的,你都需要按照当前的数据来配置它们。
代码示例:
1. (void)viewDidLoad
{[super viewDidLoad];// 如果使用 Nib 自定义 Cell[self.tableView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:nil] forCellReuseIdentifier:@"myCell"];// 如果使用代码自定义 Cell[self.tableView registerClass:[CustomCell class] forCellReuseIdentifier:@"myCell"];
}
自定义cell
自定义Cell是在开发iOS应用时常用的一种方式,它能让你更好地控制Cell的外观和行为,提高代码的可读性和可维护性。自定义Cell主要的步骤包括:
- 创建自定义Cell类:首先,需要创建一个新的类,这个类通常会继承自UITableViewCell或UICollectionViewCell。
- 添加UI元素:在这个自定义Cell类中,我们可以添加你需要的UI元素,如UILabel,UIImageView等。
- 实现初始化方法:在自定义Cell类的初始化方法中,需要初始化我们添加的UI元素,并添加到Cell的contentView上。
- 设置Cell的布局:还需要在自定义Cell类中设置UI元素的布局,可以使用Auto Layout来完成这个任务。
- 在TableView中使用自定义Cell:在TableView的tableView(_:cellForRowAt:)方法中,我们需要先通过复用标识符尝试获取一个可复用的Cell,如果没有获取到,那么就创建一个新的自定义Cell实例,并返回。
通过自定义Cell,我们可以根据自己的需求来定制Cell的外观和行为,使我们的应用更具个性化。
代码示例:
先创建一个子类myCell,从属于UITableViewCell类。
myCell.h:
#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface myCustomCell : UITableViewCell
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UILabel *subtitleLabel;
@endNS_ASSUME_NONNULL_END
myCell.m:
#import "myCell.h"@implementation myCustomCell- (void)awakeFromNib {[super awakeFromNib];// Initialization code
}- (void)setSelected:(BOOL)selected animated:(BOOL)animated {[super setSelected:selected animated:animated];// Configure the view for the selected state
}
//重写父类的初始化方法,根据需求添加自己的逻辑
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];if ([reuseIdentifier isEqualToString:@"indentifierCell"]) {_titleLabel = [[UILabel alloc] init];_titleLabel.textColor = [UIColor blueColor];_titleLabel.font = [UIFont systemFontOfSize:20];[self.contentView addSubview:_titleLabel];_subtitleLabel = [[UILabel alloc] init];_subtitleLabel.textColor = [UIColor cyanColor];_subtitleLabel.font = [UIFont systemFontOfSize:15];[self.contentView addSubview:_subtitleLabel];}return self;
}
//重写布局方法,根据需求自己设置
- (void)layoutSubviews {_titleLabel.frame = CGRectMake(40, 20, self.contentView.bounds.size.width - 40, 20);_subtitleLabel.frame = CGRectMake(40, 40, self.contentView.bounds.size.width - 40, 20);
}
@end
ViewController .h:
#import <UIKit/UIKit.h>@interface ViewController : UIViewController
<
//实现数据视图的普通协议
//数据视图的普通事件处理
UITableViewDelegate,
//实现数据视图的数据代理协议
//处理数据视图的数据代理
UITableViewDataSource
>
{//定义一个数据视图对象//数据视图用来显示大量相同格式的信息的视图UITableView* _tableview;
}@end
ViewController .m:
#import "ViewController.h"
#import "myCell.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.//创建数据视图_tableview = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) style:UITableViewStylePlain];//设置数据视图的代理对象_tableview.delegate = self;//设置数据视图的数据源对象_tableview.dataSource = self;//注册子类[_tableview registerClass:[myCustomCell class] forCellReuseIdentifier:@"indentifierCell"];[self.view addSubview:_tableview];
}
// 设置数据视图的组数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {return 1;
}
//获取每组元素的行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return 15;
}
//创建单元格对象函数
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {myCustomCell* cell = [_tableview dequeueReusableCellWithIdentifier:@"indentifierCell" forIndexPath:indexPath];cell.titleLabel.text = @"一级标题";cell.subtitleLabel.text = @"二级标题";return cell;
}
@end
总结
通过对cell的复用和自定义cell,我们可以对自己写的页面进行更多的个性化设置。以上就是本篇博客关于cell复用和自定义cell的全部内容,欢迎大家学习和指正~
相关文章:
【iOS】UI学习——cell的复用及自定义cell
目录 前言cell的复用手动(非注册)自动(注册) 自定义cell总结 前言 Cell复用和自定义Cell是在开发iOS应用时常见的一种优化技巧和定制需求。 Cell复用是UITableView或UICollectionView的一个重要优化机制。当用户滚动这些视图时…...
【详细介绍下PostgreSQL】
🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…...
基于Matlab停车场车牌识别计时计费管理系统 【W2】
简介 停车场车牌识别计时计费管理系统在现代城市管理中具有重要意义。随着城市化进程的加快和车辆数量的增加,传统的人工管理停车场的方式已经难以满足效率和精确度的要求。因此引入车牌识别技术的自动化管理系统成为一种趋势和解决方案。 背景意义 提升管理效率&a…...
码住!详解时序数据库不同分类与性能对比
加速发展中的时序数据库,基于不同架构,最流行的类别是? 作为管理工业场景时序数据的新兴数据库品类,时序数据库凭借着对海量时序数据的高效存储、高可扩展性、时序分析计算等特性,一跃成为物联网时代工业领域颇受欢迎的…...
【C/C++】实参与形参的区别
在编程中,形参(形式参数)和实参(实际参数)是函数调用中的两个基本概念,它们在函数定义和函数调用中扮演着不同的角色。 形参(Formal Parameters): 形参是在函数定义时声明…...
---异常---
我们在运行程序时总遇到各种与报错,数组越界,空指针的引用,这些在java中都称为异常 对于不同的错误都具有一个与他对应的异常类来秒描述 这是对于数组越界这个类里有的方法,这些是描述异常的 在java中有一个完整的描述异常的类的…...
python如何终止程序运行
方法1:采用sys.exit(0),正常终止程序,从图中可以看到,程序终止后shell运行不受影响。 方法2:采用os._exit(0)关闭整个shell,从图中看到,调用sys._exit(0)后整个shell都重启了(RESTAR…...
网络:用2个IP地址描述一个连接
用2个IP地址描述一个连接。这是在阅读了《TCP/IP指南》后的感想,与工业标准不同,需注意区分。 如果一个IP地址有48位,则用96位描述一个连接 对于单播,是每个IP分别描述位置。位置包括:邮局编号主机编号,采用…...
Nodejs--构建web应用
构建web应用 将从http模块中的服务器端中的request使劲按开始分析,request时间发生于网络连接建立,客户端想服务器发送报文,服务器解析报文,发现http请求的报文的时候,在出发request事件之前,已经准备好Se…...
C++ 二分查找法【面试】
在C中实现二分查找法是一个常见的面试问题。二分查找法是一种在有序数组中查找特定元素的算法,其时间复杂度为O(log n)。以下是使用C实现二分查找的示例代码: #include <iostream> #include <vector>// 二分查找法函数 int binarySearch(co…...
【Docker】docker-compose常用的构建docker容器的yml文件
docker-compose的简单使用方法,在准备好的文件夹中,mkdir好要挂载的如data或者conf文件夹,及vim docker-compose.yml,将下方的要使用的内容粘贴进去,根据自己需要添加/删除/修改一下。最后在当前文件夹直接后台启动即可…...
华为坤灵路由器初始化开局的注意事项,含NAT配置
坤灵路由器比较坑,无web界面,全程命令行配置,但是版本更新导致和华为企业路由器配置很多不一样的地方,今天介绍下 1、aaa密码复杂度修改: #使能设备对密码进行四选三复杂度检查功能。 <HUAWEI>system-view […...
HTTP!!!
HTTP 一 : 请求报文1.2 : 首行1.3 :请求头(header)1.4 : 空行1.5 : 正文 body 二: 响应报文2.2 : 首行 三 : URL 一 : 请求报文 一个HTTP 请求报文, 分成四个部分 首行 GET https://cn.bing.com/?FORMZ9FD1 HTTP/1.1请求头(header)空行正文(body) 1.2 : 首行 首行又分为三个…...
Mybatis用Map接收返回值可能出现的问题
先看一个示例 明明定义了Map<String,String> 实际内部存放的是Integer resultType是Map 也就是说Mybatis是通过反射将类型放进去的 躲过了编辑器检查 但是这样取值时候就会报类型转换错误 解决方式 resultMap 另外一种方式 用Number Integer和Double的父类 Ma…...
Web爬虫--fofa-资产信息搜集
免责声明:本文仅做技术交流与学习... 目录 fofa.py fofa搜索参数分析 fofa_api.py fofa.py import requests from bs4 import BeautifulSoup# 登录fofa之后,把自己的cookie弄过来. header{cookie: } # 参数为搜索的语法. urlhttps://fofa.info/result?qbase64dGl0bGU9IuS4…...
mySql的事务(操作一下)
目录 1. 简介2. 事务操作3. 四大特性4. 并发事务问题5. 脏读6. 不可重复读7. 幻读事务隔离级别参考链接 1. 简介 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作…...
UniApp或微信小程序中scroll-view组件使用show-scrollbar在真机Android或IOS中隐藏不了滚动条的解决办法
show-scrollbar 属性 不论是使用 变量 还是直接使用 布尔值或者直接使用 css 都是在 ios、Android 上是都没有效果。。 真机中还是出现滚动条 解决办法 添加下面CSS ::-webkit-scrollbar {display: none;width: 0 !important;height: 0 !important;-webkit-appearance: no…...
每天五分钟深度学习框架pytorch:多维tensor向量在某一维度的拼接和分割
本文重点 在深度学习中,我们常常需要完成多个向量拼接,同时也要完成向量的分割,在pytorch中已经有封装好的库,我们可以直接调用完成这部分任务。 Cat拼接 c=torch.cat([a,b],dim=0)表示将a和b按0维度进行拼接,需要注意再非dim维度,两个矩阵的维度必须是一致的,不然会拼…...
从C语言到C++(五)
从C语言到C(五) 自动类型推导尾拖返回类型类型信息推导typeid1. 定义和基本作用2. 使用方法3. 注意事项4. 示例代码5. 关联概念:RTTI decltype基本用法示例注意事项总结 基于范围的增强for循环示例 1:使用数组示例 2:使…...
数据结构——栈(Stack)详解
1. 栈(Stack) 1.1 概念 栈:一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中数据元素遵循后进先出LIFO(Last In First Out)的原则 压栈&am…...
1.Element的table表高度自适应vue3+js写法
解决方法 在页面table上添加id,动态计算每页table的最大高度 ,将高度保存在store中,每次切换路由时进行计算。 文章目录 解决方法前言一、页面table使用二、store状态库1.引入库 效果 前言 提示:状态管理使用的是pinia,用法参考…...
联想电脑电池只能充到80%,就不在充电了,猛一看以为坏了,只是设置了养护模式。
现在电池管理模式有三种: 1)常规 2)养护 3)快充 好久没有用联想的电脑了,猛一看,咱充到了80%不充了,难道电池是坏的?我们要如何设置才可以让其充电到100%呢? 右下角…...
Unity接入PS5手柄和Xbox手柄以及Android平台的(以及不同平台分析)
Unity接入PS5手柄和Xbox手柄以及Android平台的(以及不同平台分析) 介绍Unity手柄小知识PC端和编辑器上的摇杆事件和滑动事件PS5手柄Xbox手柄北通手柄 安卓环境下(安卓手机或者安卓模拟器)PS5手柄Xbox手柄北通手柄 总结 介绍 最近…...
vue+java实现简易AI问答组件(基于百度文心大模型)
一、需求 公司想要在页面中加入AI智能对话功能,故查找免费gpt接口,最终决定百度千帆大模型(进入官网、官方文档中心); 二、主要功能列举 AI智能对话;记录上下文回答环境;折叠/展开窗口&#…...
刷代码随想有感(104):动态规划——01背包问题/二维dp数组
题干: 代码: #include<bits/stdc.h> using namespace std; int n,bagweight; void solve(){vector<int>weight(n, 0);vector<int>value(n, 0);for(int i 0; i < n; i){cin>>weight[i];}for(int j 0; j < n; j){cin>…...
Docker-Portainer可视化管理工具
Docker-Portainer可视化管理工具 文章目录 Docker-Portainer可视化管理工具介绍资源列表基础环境一、安装Docker二、配置Docker加速器三、拉取Portainer汉化版本镜像四、运行容器五、访问可视化界面 介绍 Portainer是一款开源的容器管理平台,它提供了一个直观易用的…...
SqlSugar 集成
1 关于 SqlSugar SqlSugar 是 .NET/C# 平台非常优秀的 ORM 框架,目前 Nuget 总下载突破 700K,Github 关注量也高达 3.2K,是目前当之无愧的国产优秀 ORM 框架之一。 SqlSugar 官方地址:果糖网 ( SqlSugar 官网 &#…...
MySQL Connector/C++ 和 MySQL Connector/ODBC 的区别
MySQL Connector/C++ 和 MySQL Connector/ODBC 是两种不同的数据库连接工具,它们各自有不同的特点和用途。以下是它们之间的一些主要区别: 1. **编程接口**: - MySQL Connector/C++ 提供了面向对象的编程接口,它是用C++编写的,提供了C++特有的类和对象来与MySQL数据库…...
Weevil-Optimizer象鼻虫优化算法的matlab仿真实现
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 Weevil-Optimizer象鼻虫优化算法的matlab仿真实现,仿真输出算法的优化收敛曲线,对比不同的适应度函数。 2.测试软件版本以及运行结果展示…...
Web前端项目-交互式3D魔方【附源码】
交互式3D魔方 3D魔方游戏是一款基于网页技术的三维魔方游戏。它利用HTML、CSS和JavaScript前端技术来实现3D效果,并在网页上呈现出逼真的魔方操作体验。 运行效果: 一:index.html <!DOCTYPE html> <html><head><…...
2024免费推广网站/中小企业网站制作
一. 基础环境准备操作系统:Ubuntu16.04Server先sudo apt-get install vim openssh-server,便于后续上传源码以及调试。看一下现在openssh的版本:zjdubuntu:~$ ssh -VOpenSSH_7.2p2 Ubuntu-4ubuntu2.6, OpenSSL 1.0.2g 1 Mar …...
设计师网站图片/如何营销推广
DHCP 协议简介DHCP是Dynamic Host Configuration Protocol的缩写,它的前身是BOOTP。DHCP可以说是BOOTP的增强版本,是基于C/S模式的,它提供了一种动态指定IP地址和配置参数的机制。服务器端监听UDP 67端口,客户端使用UDP 68端口DHC…...
帷客分享 wordpress/seo查询5118
以下为米尔科技工程师在使用DS-5过程中总结的经验步骤,一个简单的实用HelloWorld工程。虽然工程很简单,但是对于刚入门DS-5来说,可以起到一个指导的作用。如下:步骤:1、从开始菜单启动DS-5,可以看到DS-5的欢…...
长宁免费网站制作/德州网站建设优化
前言 之前有人让我用Jenkins来做CI/CD,我拒绝了,为什么那?因为我这个人比较懒,我懒得在提交代码后,去GitLab创建一个合并请求,在去Jenkins找到这个项目去运行流水线。我想要一站式的开发体验,不要保存那么多的平台密码,不用记那么多的地址。 本篇文件就来给大家介绍一…...
建立网站不公开/免费个人网站源码
设计模式6大原则-单一职责原则 定义:一个类应该只有一个引起变化的原因。一个类只负责一项职责 如果一个类有多个职责,这些职责耦合在一起,当一个职责发生变化时,可能影响其他的职责。 如: 一个类有 A、B、C 等职责…...
简单的手机网址大全/批量优化网站软件
1、JDK (Java Development Kit)Java开发工具集 从初学者角度来看,采用JDK开发Java程序能够很快理解程序中各部分代码之间的关系,有利于理解Java面向对象的设计思想。JDK的另一个显著特点是随着Java (J2EE、J2…...