微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 tableView.reloadData() 重新加载 TableView 的问题

如何解决使用 tableView.reloadData() 重新加载 TableView 的问题

我对 swift 编程还比较陌生,并且有一个我刚遇到的问题。

我有一个 TableView 控制器,您可以在其中输入电影的名称。 如果按下“完成”按钮,新输入的名称应出现在 TableView 中并与 CoreData 一起保存。 保存也很好用,但问题是新创建的名字只有在应用重启时才会出现在列表中。

现在我认为视图会被“tableView.reloadData()”重新加载。 不幸的是,他不会。

这是我创建它的方式:

我的视图控制器:

import UIKit

class ViewController: UITableViewController {
    
    static let filmCellIndentifier = "filmCell"
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        self.tableView.reloadData() // Todo: -> don´t reload Cell Data if "DoneButton" in "CreateFilmTableViewController" isn't pressed ???
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        title = "Filmbook"
    }
    
    private func film(atIndexPath indexPath: IndexPath) -> Film {
        return CoreDataManager.shared.availableFilms()[indexPath.row]
    }
}


extension ViewController {
    override func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
        return CoreDataManager.shared.numberOfFilms
    }
    
    override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let filmCell = tableView.dequeueReusableCell(withIdentifier: ViewController.filmCellIndentifier,for: indexPath)
        let film = self.film(atIndexPath: indexPath)
        filmCell.textLabel?.text = film.title
        return filmCell
    }    
}

这里我创建了一个新电影:

import UIKit
import CoreData

class CreateFilmTableViewController: UITableViewController {

    @IBOutlet weak var datePicker: UIDatePicker!
    @IBOutlet weak var titleTextField: UITextField!
  
    @IBAction func dismissButton(_ sender: UIBarButtonItem) {
        dismiss(animated: true,completion: nil)
    }
     
    @IBAction func createFilmButton(_ sender: Any) {
        let title = titleTextField.text != nil ? titleTextField.text! : ""
        let date = datePicker.date
        CoreDataManager.shared.createFilmbook(withTitle: title,date: date)
        dismiss(animated: true,completion: nil)
    }    
}

还有我的 CoreData 管理器:

import Foundation
import CoreData

class CoreDataManager {

    static let shared = CoreDataManager()
    

    var numberOfFilms: Int {
        return availableFilms().count
    }
 
    lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "FilmbookT")
        container.loadPersistentStores(completionHandler:  { (storeDescription,error) in
            if let error = error as NSError? {
 
                fatalError("Unresolved error \(error),\(error.userInfo)")
            }
        })
        return container
    }()
    
    func createFilmbook(withTitle title: String,date: Date) {
        let film = Film(context: persistentContainer.viewContext)
        film.title = title
        film.date = date
        try! persistentContainer.viewContext.save() // Todo -> Error Handling -> ("try!")
        
    }

    func availableFilms() -> [Film] {
        
        let filmFetchRequest = NSFetchRequest<Film>(entityName: "Film")
        filmFetchRequest.sortDescriptors = [NSSortDescriptor(key: "date",ascending: true)]
        
        let availableFilms = try! persistentContainer.viewContext.fetch(filmFetchRequest) // Todo -> //Error Handling -> ("try!")
        
        return availableFilms
    }
}

你能帮我找出错误吗? 非常感谢! :)

解决方法

你应该在视图控制器中有一个表视图数据源的局部变量,所以你不应该在 CoreDataManager 中有 availableFilms()numberOfFilms。管理器的职责应该只是保存新添加的对象并返回到目前为止添加的对象。

我现在回答了一个类似的问题,请检查这个答案:https://stackoverflow.com/a/67616364/14675707

,

你有没有试听过 CoreData 的变化?创建新 Film 后,新对象可能尚未插入 Core Data 中,因此 reloadData 无法获取新对象

NotificationCenter.default.addObserver(self,selector: #selector(contextObjectsDidChange(_:)),name: Notification.Name.NSManagedObjectContextObjectsDidChange,object: nil)
NotificationCenter.default.addObserver(self,selector: #selector(contextWillSave(_:)),name: Notification.Name.NSManagedObjectContextWillSave,selector: #selector(contextDidSave(_:)),name: Notification.Name.NSManagedObjectContextDidSave,object: nil)

参考:https://medium.com/@marcosantadev/core-data-notifications-with-swift-acc8232a674e

但是,我同意@marci0907 的解决方案

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。