如何让 tableView.reloadData() 正确处理核心数据?



当我运行应用程序时,我可以填充tableview中的单元格,但是当我保存(从单独的视图控制器(并返回到tableview controller时,tableView.reloadData((被调用,但没有任何反应。我使用通知中心在弹出之前重新加载数据。

TableViewController.swift:

lazy var fetchedResultsController: NSFetchedResultsController<Pet> = {
let fetchRequest = PersistenceManager.shared.fetchRequest()
let context = PersistenceManager.shared.context
let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
return frc as! NSFetchedResultsController<Pet>
}()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(pushToAddPetViewController))
tableView.register(MainTableViewCell.self, forCellReuseIdentifier: "cell")
do {
try fetchedResultsController.performFetch()
tableView.reloadData()
} catch let err {
print(err)
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(loadList), name: NSNotification.Name(rawValue: "load"), object: nil)
}
@objc func loadList(notification: NSNotification){
DispatchQueue.main.async {
self.tableView.reloadData()
}
}

添加PetVC.swift:

func saveContext() {
// Inputs saved to coreData
PersistenceManager.shared.saveContext()
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
self.navigationController?.popViewController(animated: true)
}

您在 viewDidLoad(( 中获取了数据,当您返回视图时不会调用这些数据。您应该在viewWillAppear((中获取数据,并从该数据或通知观察器方法loadList(通知:NSNotization(重新加载。因此,在viewWillAppear((或loadList(notification: NSNotification(中添加以下代码:

do {
try fetchedResultsController.performFetch()
tableView.reloadData()
} catch let err {
print(err)
}

当你弹出 ViewController 回调到以前的 ViewController 时,不会调用 viewWillAppear((。

创建 fetchedResultsController 实例并符合 NSFetchedResultsControllerDelegate。NSFetchedResultsControllerDelegate 将观察更改并在 UI 上反映更改

lazy var fetchedResultsController: NSFetchedResultsController<Pet> = {
let fetchRequest = PersistenceManager.shared.fetchRequest()
let context = PersistenceManager.shared.context
let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
frc.delegate = self
return frc as! NSFetchedResultsController<Pet>
}()

在您看来,确实加载了

do {
try fetchedResultsController.performFetch()
} catch {
let fetchError = error as NSError
print("Unable to Save Note")
print("(fetchError), (fetchError.localizedDescription)")
}

现在实现 NSFetchedResultsControllerDelegate

extension YourController: NSFetchedResultsControllerDelegate {
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
uiTableView.beginUpdates()
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
uiTableView.endUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch (type) {
case .insert:
if let indexPath = newIndexPath {
uiTableView.insertRows(at: [indexPath], with: .fade)
}
break;
case .delete:
if let indexPath = indexPath {
uiTableView.deleteRows(at: [indexPath], with: .fade)
}
break;
case .update:
if let indexPath = indexPath, let cell = uiTableView.cellForRow(at: indexPath) as? UserCell {
configureCell(cell, at: indexPath)
}
break;
case .move:
if let indexPath = indexPath {
uiTableView.deleteRows(at: [indexPath], with: .fade)
}
if let newIndexPath = newIndexPath {
uiTableView.insertRows(at: [newIndexPath], with: .fade)
}
break;
}
}
}

Implement UITableViewDataSource & UITableViewDelegate

extension YourController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let sections = fetchedResultsController.sections else {
return 0
}
let sectionInfo = sections[section]
return sectionInfo.numberOfObjects
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PetCell", for: indexPath) as! Pet
configureCell(cell, at: indexPath)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let pet = fetchedResultsController.object(at: indexPath)
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
// handle delete (by removing the data from your array and updating the tableview)
//let user = viewModel.user(for: indexPath.row)
let pet = fetchedResultsController.object(at: indexPath)
//Delete pet and reload table
}
}
func configureCell(_ cell: Pet, at indexPath: IndexPath) {
let pet = fetchedResultsController.object(at: indexPath)
}

有关更多详细信息和代码,请遵循演示项目 https://github.com/rheyansh/CoreDataDemo

最新更新