带有NSFetchedResultsController的TableView非常闪烁

时间:2017-05-13 14:41:27

标签: swift uitableview merge nsfetchedresultscontroller flicker

我有一个带FRC的tableView。我使用NSMergeByPropertyObjectTrumpMergePolicy作为managedPolicy进行managedContext保存。

问题是当记录更新" didChange"委托方法调用3次。它按顺序要求插入,删除,更新。所以我的tableView闪烁了这么多。

我该如何防止这种情况?因为我的应用程序的每条记录都被更新了4次,所以tableView闪烁了12次..

我的委托方法:

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

func controller(controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
    switch type {
    case .insert:
        tableView.insertSections(NSIndexSet(index: sectionIndex) as IndexSet, with: .fade)
    case .delete:
        tableView.deleteSections(NSIndexSet(index: sectionIndex) as IndexSet, with: .none)
    case .move:
        break
    case .update:
        break
    }
}

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

    print("cs \(type.rawValue)")

    switch type {

    case .insert:
        tableView.insertRows(at: [newIndexPath! as IndexPath], with: .none)
        break
    case .delete:
        tableView.deleteRows(at: [indexPath!], with: .none)
        break
    case .move:
        tableView.deleteRows(at: [indexPath!], with: .none)
        tableView.insertRows(at: [newIndexPath!], with: .none)

        //tableView.moveRow(at: indexPath!, to: newIndexPath!)
        break
    case .update:
        tableView.reloadRows(at: [indexPath!], with: .none)
        break
    }
}

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

1 个答案:

答案 0 :(得分:0)

确保不清除数据库。由于以下原因,可能会出现闪烁:

        service.fetchDatasWith { (result) in
        switch result {
        case .success(let data):

            DataManager.clearData() // Cleaning
            DataManager.saveInCoreDataWith(array: data) // Saving again

            print(data)
        case .error(let message):
            DispatchQueue.main.async {
                AlertPresenter.presentAlertWith(title: "Error", message: message, controller: self)
            }
        }
    }