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

Swift实现UITableView多选搜索时已选行不显示勾选图标如何解决

问题核心原因

  1. 搜索后调用tableView.reloadData()刷新单元格时,你没有在cellForRowAt方法中判断当前行对应的项目是否已经被选中,所以不会主动设置勾选框状态
  2. didSelectRowAt/didDeselectRowAt方法存在两处逻辑错误:
    • 不应该用dequeueReusableCell获取当前点击的cell,该方法是用来获取复用队列的cell,不是当前正在显示的cell
    • 搜索状态下数据来源是projFilArr,原有代码写死从projDropDownArr取数据,会导致选中的条目和实际存储的不匹配
  3. 原有removeObject(identicalTo:)是指针匹配,过滤后数组的字典实例和原数组不一致时会移除失败,用唯一projectId判断更稳妥

修改代码

1. 调整cellForRowAt方法

在原有cellForRowAt的return cell之前新增如下判断逻辑:

// 新增:判断当前项目是否已选中,设置勾选状态
let currentProjId = self.projDropDict["projectId"] as! Int
// 按唯一projectId判断是否已选
let isSelected = selProjArr.contains { obj in
    guard let selProj = obj as? NSDictionary else { return false }
    return selProj["projectId"] as! Int == currentProjId
}
cell.setSelected(isSelected, animated: false)

2. 替换didSelectRowAt和didDeselectRowAt实现

// 取消选中逻辑
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    // 正确获取当前点击的cell
    guard let cell = tableView.cellForRow(at: indexPath) as? FilterTableViewCell else { return }
    cell.setSelected(false, animated: true)
    // 根据当前状态取对应数据源的数据
    let currentDict: NSDictionary
    if projFilArr.count > 0 {
        currentDict = self.projFilArr[indexPath.row] as! NSDictionary
    } else {
        currentDict = self.projDropDownArr[indexPath.row] as! NSDictionary
    }
    // 按projectId移除对应选中项
    for obj in selProjArr {
        guard let selProj = obj as? NSDictionary else { continue }
        if selProj["projectId"] as! Int == currentDict["projectId"] as! Int {
            selProjArr.remove(obj)
            break
        }
    }
    print(selProjArr)
}

// 选中逻辑
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    guard let cell = tableView.cellForRow(at: indexPath) as? FilterTableViewCell else { return }
    cell.setSelected(true, animated: true)
    let currentDict: NSDictionary
    if projFilArr.count > 0 {
        currentDict = self.projFilArr[indexPath.row] as! NSDictionary
    } else {
        currentDict = self.projDropDownArr[indexPath.row] as! NSDictionary
    }
    // 避免重复添加同个项目
    let isAlreadySel = selProjArr.contains { obj in
        guard let selProj = obj as? NSDictionary else { return false }
        return selProj["projectId"] as! Int == currentDict["projectId"] as! Int
    }
    if !isAlreadySel {
        selProjArr.add(currentDict)
    }
    print(selProjArr)
}

小优化建议

全局的projDropDict可以删除,所有用到的地方都改成局部变量即可,避免不同行赋值冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 02:15:03