iOS TableViewController:尝试执行插入并移动到同一索引路径

问题描述 投票:0回答:1

当从我的 NSFetchedResultsControllerDelegate 接收移动事件时,我收到以下异常:

controllerDidChangeContent:。尝试执行插入和移动到同一索引路径

extension MyViewController : 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 .insert:
            guard let newIndexPath else { return }
            tableView.insertRows(at: [newIndexPath], with: .fade)
        case .delete:
            guard let indexPath else { return }
            tableView.deleteRows(at: [indexPath], with: .fade)
        case .update:
            guard let indexPath else { return }
            tableView.reloadRows(at: [indexPath], with: .fade)
        case .move:
            guard let indexPath, let newIndexPath else { return }
            tableView.moveRow(at: indexPath, to: newIndexPath)
        @unknown default:
            print("...")
        }
    }
    
    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.endUpdates()
    }
}

在以前的 iOS 版本中有很多关于此的帖子,但最近没有。这也是苹果提供的关于如何处理插入/更新/移动事件的样板代码。我真的应该检查 at/to 索引路径是否相同吗?或者这是否表明其他地方存在问题?

ios swift nsfetchedresultscontroller
1个回答
0
投票

当您尝试在表视图的同一刷新块内执行插入和移动到同一索引路径时,通常会出现错误消息“尝试执行插入和移动到同一索引路径”。

在您的情况下,您似乎正确处理了移动事件,但 NSFetchedResultsControllerDelegate 可能将移动操作误解为插入操作。

要解决此问题,您可以更改 didChange 方法以不同地处理移动操作。您可以先删除旧索引路径中的行,然后将其插入到新索引路径中,而不是将其视为插入或删除。

在这里您可以看到如何自定义代码来处理移动操作:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
        switch type {
        case .insert:
            guard let newIndexPath = newIndexPath else { return }
            tableView.insertRows(at: [newIndexPath], with: .fade)
        case .delete:
            guard let indexPath = indexPath else { return }
            tableView.deleteRows(at: [indexPath], with: .fade)
        case .update:
            guard let indexPath = indexPath else { return }
            tableView.reloadRows(at: [indexPath], with: .fade)
        case .move:
            guard let indexPath = indexPath, let newIndexPath = newIndexPath else { return }
            tableView.beginUpdates()
            tableView.deleteRows(at: [indexPath], with: .fade)
            tableView.insertRows(at: [newIndexPath], with: .fade)
            tableView.endUpdates()
        @unknown default:
            print("...")
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.