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

标签 ios swift uitableview multi-select

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

为此,我有一个 bool 值数组来跟踪已检查和未检查的项目。但是,为了正确触发 didSelectRowAtdidDeselectRowAt 事件, TableView 还需要了解选择状态。所以我想出了两个选择,但我对这两个选择都不完全满意:

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

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
    ...
}

这可以很好地切换状态并更新后备数组。它无法做到的是让 TableView 了解每个单元格的选择状态。因此,在重新加载时,会触发错误的选择事件(选择/取消选择),然后要求用户最初点击两次以更改状态。现在,我可以通过处理 didSelectRowAtdidDeselectRowAt 中的两种状态来解决此问题,但它与控件的状态相矛盾,并且可能会在以后导致问题。

让 TableView 跟踪状态:

在这里,我替换了

if isSelected(index: indexPath.row) {

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

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

`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 委托(delegate)方法或将 allowsMultipleSelection 设置为 true

关于ios - 如何在 iOS 中以编程方式预选多选 UITableView 中的单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68305790/

相关文章:

swift - 通过符合 Swift 2 中的协议(protocol)扩展类型化数组

ios - UITableViewCell 中的 UITextView 防止 segue

ios - 将 UITableViewController 插入其他 UIView

ios - 比较值并在 uitableview 中显示特定结果

ios - 如何改进 ios 中数字输入的语音识别?

ios - 从表中删除引用对象 - Swift

ios - 为什么这个 UIImageView 动画会泄漏?

ios - Swift 中的 RSA 公钥加密

ios - 如何在 Socket.io Swift4 中发出事件

objective-c - 如何使用 UIDocumentInteractionController 在另一个应用程序中打开文件?