调用scrollToRowAtIndexPath后UITableView为何生成多余复用单元格?
UITableView滚动到指定行后出现多余复用单元格问题解决
问题场景
表格共包含30个单元格,在viewDidLoad中设置5秒后滚动至第15行,滚动到原本不可见的单元格后,UITableView生成了多余的复用单元格,现象如下:

问题代码
@implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [self.view addSubview:self.tableView]; self.tableView.frame = self.view.frame; self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; self.tableView.separatorColor = UIColor.whiteColor; self.tableView.estimatedRowHeight = 52; [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:NSStringFromClass(UITableViewCell.class)]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:15 inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; }); } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return 30; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(UITableViewCell.class)]; cell.backgroundColor = [self.class randomColorWithAlpha:1]; return cell; }
问题原因
核心问题是仅设置了estimatedRowHeight但未明确指定精确行高。UITableView依赖行高计算可视区域的单元格数量,当使用估算行高且所有行高为固定值时,估算逻辑会出现偏差,滚动到非初始可视区域的行时,会提前创建超出实际需求的单元格用于复用,最终导致多余单元格出现。
解决方案
根据你的行高需求,可选择以下两种方式解决:
方案1:固定行高,移除估算行高设置
如果表格行高是固定值(示例中为52),直接设置明确的rowHeight,删除estimatedRowHeight的配置:
// 替换原estimatedRowHeight设置 self.tableView.rowHeight = 52; // 移除 self.tableView.estimatedRowHeight = 52;
方案2:保留估算行高,实现精确估算方法
若需要保留动态行高的扩展性,可实现精确的估算行高方法,确保估算值与实际行高一致:
// 实现精确的行高估算方法 - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { return 52; // 返回与实际行高一致的值 } // 同时实现实际行高方法(固定行高场景) - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 52; }
原理说明
当UITableView能获取到精确的行高信息(无论是直接设置rowHeight,还是通过精确的估算+实际行高方法),就能准确计算出当前可视区域所需的单元格数量,不会因估算偏差提前创建多余的复用单元格,从而解决该问题。
内容的提问来源于stack exchange,提问作者李传师
相关产品推荐
相关产品推荐

