Swift实现UITableView多选搜索时已选行不显示勾选图标如何解决
问题核心原因
- 搜索后调用
tableView.reloadData()刷新单元格时,你没有在cellForRowAt方法中判断当前行对应的项目是否已经被选中,所以不会主动设置勾选框状态 didSelectRowAt/didDeselectRowAt方法存在两处逻辑错误:- 不应该用
dequeueReusableCell获取当前点击的cell,该方法是用来获取复用队列的cell,不是当前正在显示的cell - 搜索状态下数据来源是
projFilArr,原有代码写死从projDropDownArr取数据,会导致选中的条目和实际存储的不匹配
- 不应该用
- 原有
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
相关产品推荐
相关产品推荐

