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

Cell的复用及自定义Cell

Cell的复用及自定义Cell

  • 前言
  • Cell的复用
    • 非注册方法(手动)
    • 注册方法(自动)
  • 自定义Cell

前言

在iOS开发中,UITableViewUICollectionView 是常用的列表视图控件,而 Cell复用自定义Cell 是优化其性能和灵活性的关键技术。

Cell的复用

UITableViewUICollectionView 显示大量数据时,系统不会为每个数据项都创建一个新的 Cell,系统会维护一个可重用的Cell队列,当Cell滚出屏幕时会被放入队列,而当需要显示新的Cell时,系统会优先从队列中取出可重用的Cell进行配置,即 复用已经滚出屏幕的Cell,以减少内存占用和提升性能。

实现Cell的复用有两种方法:

  • 非注册方法(即手动判空)
  • 注册方法(即使用Cell的自动注册机制)

非注册方法(手动)

手动复用Cell的方法步骤:

  • 注册Cell类(即在设置复用标识符):创建一个局部字符串变量作为Cell的类型。在创建Cell时,将这个标识符作为参数传入
  • 复用Cell:通过调用UITableViewUICollectionView的dequeueReusableCell(withIdentifier:)方法来请求一个已经不显示在屏幕但是没有被销毁的Cell来显示新的Cell
  • 配置Cell:重新配置复用的Cell以显示新的数据

代码演示:

- (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;
}

注册方法(自动)

与手动复用Cell的区别在于不用手动判空。

自动复用Cell的方法步骤:

  • 注册Cell类型:创建一个局部字符串变量作为Cell的类型。在创建Cell时,将这个标识符作为参数传入
  • 请求复用的Cell:使用dequeueReusableCell(WithIdentifier:)获取可复用的cell
  • 创建新的Cell:不用判空,如果dequeueReusableCell(WithIdentifier:)方法返回nil,自动创建一个新的Cell并返回
  • 配置Cell:重新配置复用的Cell以显示新的数据

代码演示:

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {static NSString *strID = @"id";MyTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier: strID];cell.backgroundColor = [UIColor redColor];return cell;
}

自定义Cell

默认的 UITableViewCellUICollectionViewCell 样式有限,通常需要 自定义Cell 来满足UI需求。

自定义Cell的方法步骤:

  • 初始化阶段
    • ViewController加载时创建并配置UITableView
    • 注册自定义Cell类与复用标识的关联
  • Cell创建阶段
    • 当tableView需要显示cell时,调用cellForRowAtIndexPath:
    • 系统首先尝试从复用队列中获取cell
    • 如果没有可复用的cell,系统会调用initWithStyle:reuseIdentifier:初始化新的cell
    • 在初始化方法中创建并配置label1和label2
  • 布局阶段
    • 当cell需要显示时,系统调用layoutSubviews
    • 在layoutSubviews中设置两个label的精确位置
  • 复用阶段
    • 当cell滚出屏幕时,会被放入复用队列
    • 当新的cell需要显示时,优先从复用队列中获取

代码演示:

UICellTableViewCell.h

定义一个继承UITableViewCell的Cell类

#import <UIKit/UIKit.h>@interface UICellTableViewCell : UITableViewCell
@property(nonatomic, strong) UILabel *label1;
@property(nonatomic, strong) UILabel *label2;
@end

UICellTableViewCell.m

初始化方法和布局方法

#import "UICellTableViewCell.h"@implementation UICellTableViewCell-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];if ([reuseIdentifier isEqual:@"cell"]) {_label1 = [[UILabel alloc] init];_label1.textColor = [UIColor greenColor];_label1.font = [UIFont systemFontOfSize:20];[self.contentView addSubview:_label1];_label2 = [[UILabel alloc] init];_label2.textColor = [UIColor cyanColor];_label2.font = [UIFont systemFontOfSize:15];[self.contentView addSubview:_label2];}return self;
}-(void)layoutSubviews {_label1.frame = CGRectMake(100, 20, self.contentView.bounds.size.width - 40, 20);_label2.frame = CGRectMake(100, 40, self.contentView.bounds.size.width - 40, 20);
}

注册自定义Cell类,将tableView添加到视图

//ViewController.h
#import <UIKit/UIKit.h>@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {UITableView  *_tableView;
}@end
//ViewController.m
#import "ViewController.h"
#import "UICellTableViewCell.h"
@interface ViewController ()@end
@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];_tableView.delegate = self;_tableView.dataSource = self;[_tableView registerClass:[UICellTableViewCell class] forCellReuseIdentifier:@"cell"];[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 {UICellTableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:@"cell"];cell.label1.text = @"一级标题";cell.label2.text = @"二级标题";return  cell;
}
@end

注意:所有子视图都应该添加到contentView上,而不是直接添加到cell本身

http://www.xdnf.cn/news/13092.html

相关文章:

  • STM32嵌套向量中断控制器(NVIC)及外部中断使用案例分析
  • GAMES202-高质量实时渲染(Assignment 4)
  • 【Python基础】异常捕获知识梳理
  • Device Mapper 机制
  • Redis数据结构选择策略--String?Hash?怎么选?
  • C++ Saucer 编写Windows桌面应用
  • AI——DeepSeek+LangChain+streamlit 实现智能汽车维修服务
  • 视觉slam十四讲实践部分记录——ch2、ch3
  • 字节开源代码模型——Seed-Coder 本地部署教程,模型自驱动数据筛选,让每行代码都精准落位!
  • ​第八章:漏洞里的人间烟火
  • Linux线程与进程关系及底层实现
  • 瑞数信息入选Gartner《中国API管理市场指南》
  • 亚马逊测评,采购环境安全需要解决哪些问题,提高成功率
  • 验证redis数据结构
  • 课堂笔记:吴恩达的AI课(AI FOR EVERYONE)-第一周part2 人工智能术语人工智能公司应该怎么做
  • 恶补电源:1.电桥
  • 【第一章:人工智能基础】01.Python基础及常用工具包-(3)常用数据科学工具包
  • 性能测试分析
  • 深度剖析Diffusion与Transformer在图像生成中的计算逻辑与融合之道
  • 火山引擎云服务器使用感怎么样
  • HarmonyOS运动开发:打造你的专属运动节拍器
  • python打卡day49
  • 大数据学习(135)-Linux系统性指令
  • Windows 环境下,使用 ESP32 JTAG 接口进行固件下载
  • 浅谈互联网主流通信协议
  • 【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
  • 【堆垛策略】设计方法
  • SAP软件年结科目余额结转详解
  • ShuffleNet 改进:与通道注意力机制(CAM)的结合实现
  • 如何用Coze+Fetch快速构建结构化文档