【问题标题】:Applying NSDiffableDataSourceSnapshot to UITableViewDiffableDataSource cause 'NSInternalInconsistencyException'将 NSDiffableDataSourceSnapshot 应用于 UITableViewDiffableDataSource 导致“NSInternalInconsistencyException”
【发布时间】:2021-07-02 03:48:14
【问题描述】:

我正在尝试为我的 tableview 实现 UITableViewViewDiffableDataSource。我的代码编译得很好,但是我第一次对其应用快照时一直遇到此错误,并出现以下错误:

由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效参数不满足:section

这是我的代码:

BaseDisplayManager

class BaseDisplayManager: NSObject, UITableViewDelegate, BaseDiffableDataSourceDelegate {
   var tableData = [[BaseViewModelProtocol]]()
   var sections: [DiffableSection] = []
...

   func setupDiffableDataSource(forTableView tableView: UITableView) {
      dataSource = BaseDiffableDataSource(tableView: tableView, cellProvider: { (tableView, indexPath, model) -> UITableViewCell? in
          guard let model = model as? BaseViewModelProtocol else { return nil }
          let cell = tableView.dequeueReusableCell(withIdentifier: model.cellIdentifier, for: indexPath)
          (cell as? TableViewCell)?.model = model
          (cell as? NoSwipeTableViewCell)?.model = model
          return cell
      })

      dataSource.delegate = self
   }

   func reloadSnapshot() {
      var snapshot = NSDiffableDataSourceSnapshot<AnyHashable, AnyHashable>()
      snapshot.appendSections(sections.map { $0.sectionIdentifier() })
      sections.forEach { [weak self] section in
          guard let items = self?.tableData[section.sectionIndex()] as? [AnyHashable] else { return }
          snapshot.appendItems(items, toSection: section.sectionIdentifier())
      }
    
      dataSource.apply(snapshot, animatingDifferences: true)
   }

DiffableSection

protocol DiffableSection {
  func sectionIndex() -> Int
  func sectionIdentifier() -> AnyHashable
}

BaseDiffableDataSource

protocol BaseDiffableDataSourceDelegate: class {
   func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
   func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
   func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool
   func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
}

class BaseDiffableDataSource: UITableViewDiffableDataSource<AnyHashable, AnyHashable> {

   weak var delegate: BaseDiffableDataSourceDelegate! = nil

   override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return delegate.tableView(tableView, canEditRowAt: indexPath)
   }

   override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    return delegate.tableView(tableView, commit: editingStyle, forRowAt: indexPath)
   }

   override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    return delegate.tableView(tableView, canMoveRowAt: indexPath)
   }

   override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
    return delegate.tableView(tableView, moveRowAt: sourceIndexPath, to: destinationIndexPath)
   }
}

}

【问题讨论】:

  • 我确定错误原因是tableView.estimatedRowHeight的定义,tableView.estimatedSectionFooterHeight,tableView.estimatedSectionHeaderHeight = 0.0

标签: uitableview uikit swift5 diffabledatasource nsdiffabledatasourcesnapshot


【解决方案1】:

我在 UITableViewController 的子类 ViewController 中遇到了同样的问题。

对我来说,我是在配置我的数据源并在viewWillAppear() 中应用快照并调用super.viewWillAppear() 之前。删除超级调用就可以了。

【讨论】:

    猜你喜欢
    • 2020-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多