如何在 viewWillAppear 上重新加载 fetchedResultsController?

Posted

技术标签:

【中文标题】如何在 viewWillAppear 上重新加载 fetchedResultsController?【英文标题】:How to reload fetchedResultsController on viewWillAppear? 【发布时间】:2017-11-16 05:20:07 【问题描述】:

因为我想在关闭弹出视图控制器后重新加载表视图和数据。

这个获取控制器似乎只在视图加载时运行,因为它保留了旧数据。视图出现时如何运行或刷新获取控制器?

var fetchedResultsController: NSFetchedResultsController<Record> 
    if _fetchedResultsController != nil 
        return _fetchedResultsController!
    

    let fetchRequest: NSFetchRequest<Record> = Record.fetchRequest()
    fetchRequest.fetchBatchSize = 20
    let accBtn = UserDefaults().value(forKey: "BtnName") as! String
    let sortDescriptor = NSSortDescriptor(key: "createdAt", ascending: false)
    fetchRequest.sortDescriptors = [sortDescriptor]
    fetchRequest.predicate = NSPredicate(format: "%K == %@", "accountbook" , "\(accBtn)")
    let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: "createdAt", cacheName: nil)
    aFetchedResultsController.delegate = self
    _fetchedResultsController = aFetchedResultsController

    do 
        try _fetchedResultsController!.performFetch()
     catch 
        let nserror = error as NSError
        fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
    

    return _fetchedResultsController!


var _fetchedResultsController: NSFetchedResultsController<Record>? = nil

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


func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) 
    switch type 
    case .insert:
        self.tableView.insertSections(IndexSet(integer: sectionIndex), with: .fade)
    case .delete:
        self.tableView.deleteSections(IndexSet(integer: sectionIndex), with: .fade)
    default:
        return
    


func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) 
    switch type 
    case .insert:
        tableView.insertRows(at: [newIndexPath!], with: .fade)
    case .delete:
        tableView.deleteRows(at: [indexPath!], with: .fade)
    case .update:
        self.configureCell(tableView.cellForRow(at: indexPath!)! as! DashboardCell, withRecordItem: anObject as! Record)
    case .move:
        tableView.moveRow(at: indexPath!, to: newIndexPath!)
    


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

【问题讨论】:

我也遇到了同样的问题...有什么解决办法吗? 【参考方案1】:

如果您在托管对象上下文中更改数据时您的 ViewController 在内存中,则获取的结果控制器委托应该可以工作。

在您当前的实现中,每次更改时您都会更新 tableview,但并不总是建议这样做。我猜你需要跑题,只在上面实现didChangeContentreloadData

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) 
    self.tableView.reloadData()

【讨论】:

我试过这个。关闭 pop vc 后,表格刷新但列表有问题(某些数据未显示),当我选择单元格时,出现此错误 'cannot access fetched objects before -performFetch:' @WanJern:你删除了所有其他的委托方法吗? 你的意思是我必须删除 - controllerWillChangeContent, didChange section &amp; anObject 吗?但我需要它来更新我的用户界面并将相同的日期项分组到一个部分中。@Puneet Sharma 是的,我是这个意思。在 didChangeContent 上调用 tableView 上的 reloadData,将完成所有需要的更改。 好的,我尝试删除它,但在我关闭弹出 vc 后它仍然显示旧数据...

以上是关于如何在 viewWillAppear 上重新加载 fetchedResultsController?的主要内容,如果未能解决你的问题,请参考以下文章

试图在 viewWillAppear 中重新加载数据()

如何快速从另一个视图控制器重新加载表格视图

如何刷新视图控制器

确定 viewWillAppear 来自打开应用程序,还是取消选择模式

在 UIViewController 上加载数据:viewDidLoad 和 viewWillAppear - 啥是正确的逻辑?

Swift:如何使用导航控制器重新加载表格