You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用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,提问作者李传师

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:37:33