首页 > 解决方案 > 带有 NSFetchedResultsControllerDelegate 更新的 UISwipeActionsConfiguration

问题描述

我有一个 UITableViewDataSource,它也是一个 NSFetchedResultsControllerDelegate。

在表的委托上我实现:(completionHandler 在这里故意省略)

func tableView(
    _ tableView: UITableView,
    trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {

    let delete = UIContextualAction(style: .destructive, title: "Delete") { (action, sourceView, completionHandler) in

      let object = self.object(at: indexPath)

      do {
        try ObjectManager.delete(object)
      } catch let error as NSError {
        print(error)
      }
    }

    let config = UISwipeActionsConfiguration(actions: [delete])
    config.performsFirstActionWithFullSwipe = true
    return config
  }

在数据源上,我像这样符合获取的结果控制器委托:

extension UserPrescriptionsTableViewDataSource: NSFetchedResultsControllerDelegate {

  // MARK: - NSFetchedResultsControllerDelegate

  func controllerWillChangeContent(
    _ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView?.beginUpdates()
  }

  func controller(
    _ controller: NSFetchedResultsController<NSFetchRequestResult>,
    didChange anObject: Any,
    at indexPath: IndexPath?,
    for type: NSFetchedResultsChangeType,
    newIndexPath: IndexPath?) {

    switch type {

    case .delete:
      guard let path = indexPath else { return }
      tableView?.deleteRows(at: [path], with: .automatic)
    case .insert:
      guard let newPath = newIndexPath else { return }
      tableView?.insertRows(at: [newPath], with: .automatic)
    case .move:
      guard let path = indexPath, let newPath = newIndexPath else { return }
      tableView?.deleteRows(at: [path], with: .automatic)
      tableView?.insertRows(at: [newPath], with: .automatic)
    case .update:
      guard let path = indexPath else { return }
      tableView?.reloadRows(at: [path], with: .automatic)
    }
  }

  func controllerDidChangeContent(
    _ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView?.endUpdates()
  }
}

滑动操作更新通过在操作自己的块中调用的 completionHandler 更新或不更新 UI:

completionHandler(true) // animates row removal
completionHandler(false) // does not remove the row

我的问题是滑动动画在使用中感觉正确,当我在操作完成时返回 false 时,委托确实删除了该行,但它与用户的操作不匹配。在试用中,我通过以下方式避免重复调用:

我试过了:

标签: iosswiftuitableviewnsfetchedresultscontroller

解决方案


推荐阅读