UITableView 的选中问题

354 阅读1分钟

需求是可以一键选中所有的cell,在实现的过程中,考虑使用系统的选中的方法

tableView.allowsMultipleSelection = true

cell.selectionStyle = .default

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
  。。。
  selectItems.accept(selectItems.value.filter { $0.name != model.name })
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
 。。。
 selectItems.accept(tempArr)
}

override func setSelected(_ selected: Bool, animated: Bool) {
     super.setSelected(selected, animated: animated)
     selectBtn.isSelected = selected
}

但是在实现的过程中,发现了不少的问题

1.设置了cell的的选中的状态,selectBtn并不能正确的更新状态,因为setSelected这个方法会执行多次,didSelectRowAt 会调用两次,具体原因不详。

2.全选所有的cell,当第一次点击某个cell的时候,并不会执行didDeselectRowAt的方法,而是执行didSelectRowAt 方法,所以如果代理逻辑分别在两个方法中实现的话,就出现混乱了。就是会出现cell.isSelected 无论是true还是false 都有可能执行didSelectRowAt这个方法。

不知道具体原因,可能是我实现的方式不对。

所以最后放弃系统的选中状态,通过模型来更新selectBtn 的状态

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   tableView.deselectRow(at: indexPath, animated: true)

 。。。        
if selectItems.value.contains(where: { $0.name ?? "" == model.name ?? ""}) {
            cell.selectBtn.isSelected = true
        } else {
            cell.selectBtn.isSelected = false
        }
        return cell
    }

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
。。。        
if selectItems.value.contains(where: { $0.name ?? "" == model.name ?? ""}) {
            selectItems.accept(selectItems.value.filter { $0.name != model.name })
            cell.selectBtn.isSelected = false
        } else {
            var tempArr = selectItems.value
            tempArr.append(model)
            selectItems.accept(tempArr)
            cell.selectBtn.isSelected = true
        }
    }