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

Swift3 嵌套UITableView didSelectRowAt触发后多Cell同索引行选中问题

页面效果示意图

问题原因

  • 你当前用了全局共享的isSelectedIndex、isIndexSelected两个变量存储选中状态,所有父Cell内嵌的子UITableView都复用这组状态变量,自然会出现相同索引行同步选中的问题
  • 子UITableView选中后你调用的是父tableViewtblViewAudit的全量重载,状态没有和对应的父Cell、子选项绑定,也会导致选中状态错乱

解决步骤

1. 改造选中状态存储结构

不要用全局的单个变量存选中,改为用字典存储每个父Cell对应选中的子选项索引,结构示例:

// key为父Cell的索引(即父tableView的indexPath.row),value为该父Cell下选中的子选项行索引,未选中则不存储对应key
var selectedIndexMap: [Int: Int] = [:]

2. 给子UITableView绑定对应父Cell的索引

在父Cell(AuditQuestionsTblCell)定义时,增加parentIndex属性存储当前父Cell在父tableView中的位置,赋值父Cell时将索引同步给子tableView的tag:

// 父tableView的cellForRowAt中修改代码
cell?.tblViewAnswer.tag = indexPath.row // 子tableView的tag等于父cell的索引
cell?.parentIndex = indexPath.row

3. 替换子Cell的选中状态判断逻辑

子tableView渲染Cell时,先取当前子tableView对应的父索引,从selectedIndexMap中查询该父Cell下的选中行,再判断当前行的选中状态:

// 替换原有子cell配置中的选中判断代码
let parentIndex = tableView.tag
let currentSelectedIndex = selectedIndexMap[parentIndex] ?? -1
if currentSelectedIndex == indexPath.row {
    cell?.viewOption.backgroundColor = UIColor.blue
} else {
    cell?.viewOption.backgroundColor = UIColor.lightGray
}

4. 改造选中事件逻辑

选中子Cell时仅重载当前对应的子tableView,无需全量重载父tableView,避免状态错乱同时提升性能:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    guard tableView.tag != 101 else { return } // 过滤父tableView的选中事件
    let parentIndex = tableView.tag
    // 切换选中状态:已选中则取消,未选中则标记当前行为选中
    if selectedIndexMap[parentIndex] == indexPath.row {
        selectedIndexMap.removeValue(forKey: parentIndex)
    } else {
        selectedIndexMap[parentIndex] = indexPath.row
    }
    // 仅重载当前子tableView
    tableView.reloadData()
}

5. 额外优化点

  • 如果不同父Cell的子选项列表不同,不要全局共用arrOptionList数据源,需将子选项列表存储到父数据源的对应字段中,渲染时根据父索引取对应子选项数组
  • 子cell上的按钮点击事件methodOptionSelection也需要按照上述逻辑调整,不要依赖全局变量判断状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 21:54:02