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

使用Ramotion folding-cell库搜索过滤后点击行触发行数异常错误

解决Folding Cell过滤后reloadData的行数不匹配错误

这个问题我之前在使用Ramotion的Folding Cell库时也碰到过——核心原因是Folding Cell内部维护了自己的状态(比如展开单元格的记录、行高缓存等),你只修改了外部的数据源和硬编码的kRowsCount,但库内部的状态没同步更新,导致TableView刷新时出现预期行数和实际内部状态不匹配的冲突。

下面是具体的解决步骤,亲测有效:

1. 抛弃硬编码的行数常量,以数据源为唯一可信来源

首先删掉kRowsCount这种硬编码的行数定义,所有和行数相关的地方直接用过滤后的数据源count。比如在TableView的数据源方法里:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return filteredData.count // 直接返回过滤后的数据源数量
}

硬编码的数值很容易和实际数据源脱节,这是最容易踩的坑。

2. 过滤前重置Folding Cell的展开状态

Folding Cell会记录当前展开的单元格位置,过滤后原来的展开行可能已经不在新的数据源里了,必须先把这些状态清空:

func filterData(with searchText: String) {
    // 1. 先折叠所有展开的单元格
    if let expandedIndexPath = tableView.indexPathForSelectedRow {
        if let foldingCell = tableView.cellForRow(at: expandedIndexPath) as? FoldingCell {
            foldingCell.fold(animated: false) // 无动画折叠,避免视觉错乱
        }
        tableView.deselectRow(at: expandedIndexPath, animated: false)
    }
    
    // 2. 过滤数据源
    filteredData = originalData.filter { $0.title.contains(searchText) }
    
    // 3. 刷新表格
    tableView.reloadData()
}

如果你的Folding Cell版本里有专门维护展开状态的属性(比如expandedIndices数组),记得也要清空它:

// 若存在该属性,添加这行
foldingCell.expandedIndices.removeAll()

3. 确保行高方法和数据源同步

检查tableView(_:heightForRowAt:)方法,确保它也是基于过滤后的数据源返回行高,而不是依赖旧的状态:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // 确保indexPath在filteredData的范围内(避免越界)
    guard indexPath.row < filteredData.count else { return 0 }
    // 根据Folding Cell的状态返回对应行高
    return isCellExpanded(at: indexPath) ? expandedHeight : foldedHeight
}

为什么会出现这个错误?

Folding Cell为了实现流畅的折叠/展开动画,会在内部缓存展开单元格的位置、行高等状态。当你直接修改行数常量但没重置这些内部状态时,库仍然认为表格有11行,但TableView根据数据源只渲染3行,两者的状态不一致就会触发系统的行数校验错误。

内容的提问来源于stack exchange,提问作者 coinhndp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:18:20