【问题标题】:Tableview deleting rows and sections表格视图删除行和部分
【发布时间】:2021-01-03 01:21:30
【问题描述】:

我已经实现了以下删除机制:在删除操作时 tableView 删除选定的行,如果部分没有任何行,它将被删除。

我的机制是这样的:

guard let selectedRows = self.tableView.indexPathsForSelectedRows,
      let indexPath = self.tableView.indexPathForSelectedRow else { return }
                
self.tableView.beginUpdates()
self.dataSource[indexPath.section].rows.remove(at: indexPath.item)
                
if self.dataSource[indexPath.section].rows.isEmpty {
    self.dataSource.remove(at: indexPath.item)
    self.tableView.deleteSections(IndexSet(arrayLiteral: indexPath.section), with: .fade)
}
                
self.tableView.deleteRows(at: selectedRows, with: .fade)
self.tableView.endUpdates()

我的数据源对象:

struct DataSource {
    var section:String
    var rows:[Row]
}

struct Row {
    var data:String
}

问题是当我选择多行并尝试删除所选行时,我很喜欢以下消息:

无效更新:第 0 节中的行数无效。更新后现有节中包含的行数 (5) 必须等于更新前该节中包含的行数 (6),加上或减去从该节插入或删除的行数(0 插入,2 删除)加上或减去移入或移出该节的行数(0 移入,0 移出)。'

当我删除一行时,我的机制可以正常工作,正如预期的那样。甚至删除一个空白部分。任何想法,我错在哪里?非常感谢。

【问题讨论】:

  • 据我所知,self.dataSource[indexPath.section].rows.remove(at: indexPath.item) 只删除了一个数组项。
  • 如何做取决于你。 indexPath 是选定索引的数组。 developer.apple.com/documentation/foundation/indexpath
  • 如果不需要,不要尽可能多地使用self.。它不必要地降低了可读性并增加了额外的长度而没有太多收获。
  • 您检查该部分的数据源是否为空。然后从 tableview 中删除该部分。但是您没有确认 tableview 的部分是空的。如果在非空部分上调用 tableView.deleteSections,我怀疑它正在删除该行,然后是该部分。然后,您的代码会降级并调用 tableView.deleteRows。这可能会导致重复删除。
  • @Bugrym 我明白了。只是一个想法:将代码移动到一个函数中,然后像 self.doStuff() 这样调用函数。这也可以提高整体可读性

标签: ios swift uitableview tableview delete-row


【解决方案1】:

解决方案:只需添加倒排 indexPath 数组。 let invertedIndexPathes = selectedRows.sorted(by: >)

固定机制:

guard let selectedRows = self.tableView.indexPathsForSelectedRows,
       let indexPath = self.tableView.indexPathForSelectedRow else { return }

let invertedIndexPathes = selectedRows.sorted(by: >)
self.tableView.beginUpdates()
            
for itemIndexPath in invertedIndexPathes {
    self.dataSource[itemIndexPath.section].rows.remove(at: itemIndexPath.row)
    self.tableView.deleteRows(at: [itemIndexPath], with: .fade)
    self.tableView.reloadData()
}
            
if self.dataSource[indexPath.section].rows.isEmpty {
    self.dataSource.remove(at: indexPath.item)
    self.tableView.deleteSections(IndexSet(arrayLiteral: indexPath.section), with: .fade)
}
            
self.tableView.endUpdates()

【讨论】:

    猜你喜欢
    • 2011-02-15
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    • 2020-05-19
    • 1970-01-01
    相关资源
    最近更新 更多