微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 iOS 的多选 UITableView 中以编程方式预选单元格

如何解决如何在 iOS 的多选 UITableView 中以编程方式预选单元格

我使用 UITableView 来让用户从多个给定选项中进行选择,并允许进行多项选择。我还希望用户稍后返回到此视图并更改先前所做的选择,这意味着我必须能够使用先前的选择加载和初始化表。此外,用户可以点击“全选”按钮,该按钮应以编程方式设置所有选项。

为此,我有一个布尔值数组,用于跟踪已选中和未选中的项目。但是,为了正确触发 didSelectRowAtdiddeselectRowAt 事件,table view 还需要知道选择状态。所以我想出了两个选项,但我都不满意:

使用我自己的数组设置单元格附件类型:

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
    return items.count
}

func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    let cell: UITableViewCell! = tableView.dequeueReusableCell(withIdentifier: "MyCell",for: indexPath)
    cell.textLabel!.text = items[indexPath.row].name
    if items[indexPath.row].isSelected {
        cell!.accessoryType = .checkmark
    } else {
        cell!.accessoryType = .none
    }
    return cell
}

func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) {
    
    let cell = tableView.cellForRow(at: indexPath)
    cell!.accessoryType = .checkmark
    ...
}

func tableView(_ tableView: UITableView,diddeselectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath)
    cell!.accessoryType = .none
    ...
}

这很好地切换状态并更新后备数组。它没有做的是让表格视图知道每个单元格的选择状态。因此,在重新加载时,会触发错误的选择事件(did select/did deselect),然后要求用户最初点击两次以更改状态。现在我可以通过处理 didSelectRowAtdiddeselectRowAt 中的两个状态来解决这个问题,但它与控件的状态相矛盾,以后可能会导致问题。

让表格视图跟踪状态:

这里,我换了

if isSelected(index: indexPath.row) {

if let selectedRows = tableView.indexPathsForSelectedRows,selectedRows.contains(indexPath) {

这使表格视图在内部保持更新,但我还没有找到一种很好的方法来以编程方式设置状态,当用户返回带有一些预选项目的表格或单击“全选”时。尝试遍历我的数组并使用例如

`tableView.selectRow(at: IndexPath(row: index,section: 0),animated: false,scrollPosition: .none)`

(如对类似问题的回答所建议的)在适用的情况下并没有导致预期的结果。

使用预选值初始化我的表并在单击“全选”时更新它的最佳方法是什么?

解决方法

您应该完全使用您的数据模型来管理它。

func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath)

    // Assumption: item is a class,so changes are reflected in array as expected
    let item = items[indexPath.row]
    item.isSelected.toggle()

    cell!.accessoryType = item.isSelected ? .checkmark : .none
}

这样一来,数据模型就始终存在一个事实来源。您的 tableView 实例不需要为您记住任何内容,它由您提供的数据驱动。

如果你这样做,你不需要实现didDeselect委托方法或将allowsMultipleSelection设置为true

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。