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

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本身

相关文章:

  • 【Zephyr 系列 16】构建 BLE + LoRa 协同通信系统:网关转发与混合调度实战
  • EasyImage实战:结合内网穿透技术实现私有图床部署过程
  • 创客匠人:赋能创始人IP打造,破局知识变现的黄金路径
  • Android实践:查看远程文档
  • 接口自动化测试-效果展示
  • 2025年文化交流与创新教育国际会议(ICCEIE 2025)
  • 合成来源图以在入侵检测系统中进行数据增强
  • RAG质量评估
  • 【易飞】通过信息传递触发时机复制生成品号实现复制品号自动带出原自定义字段数据
  • 马克思主义与社会科学方法论通俗版
  • MeanFlow:何凯明新作,单步去噪图像生成新SOTA
  • DAY 19 常见的特征筛选算法
  • 本周四19点,《国产网络音频传输的今天和明天》开讲!
  • 软件工程教学评价
  • 性能测试|有限元软件分析——以Abaqus隐式静力学求解为例
  • 【JavaSE】多线程基础学习笔记
  • 网络基础概念(网络基础)
  • Excel表格数据导入数据库
  • 亮相GAITC 2025,中科曙光全面赋能AI基础设施
  • 【为什么RabbitMQ能够控制事务?控制事务的原理】
  • 公司外贸网站/网络营销推广机构
  • 品牌vi设计是什么/seoul是什么品牌
  • 在线房屋设计网站/济南网络优化哪家专业
  • 怎么在工商局网站做股东变更/专业的制作网站开发公司
  • 做一个网站需要哪些资源/拼多多搜索关键词排名
  • 菏泽网站建设哪家好/百度收录批量查询工具