使用 tableView.reloadData() 重新加载 TableView 的问题
Posted
技术标签:
【中文标题】使用 tableView.reloadData() 重新加载 TableView 的问题【英文标题】:Problems to reload TableView with tableView.reloadData() 【发布时间】:2021-05-20 04:49:50 【问题描述】:我对使用 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
你能帮我找出错误吗? 非常感谢! :)
【问题讨论】:
按下done
按钮时,您是否尝试过reloadData
?
是的,我试过了,但是没有效果...
【参考方案1】:
您应该在视图控制器中有一个表视图数据源的局部变量,因此您不应该在 CoreDataManager 中有 availableFilms() 和 numberOfFilms。经理的职责应该只是保存新添加的对象并返回目前添加的对象。
我现在回答了一个类似的问题,请查看这个答案:https://***.com/a/67616364/14675707
【讨论】:
【参考方案2】:你有试过听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, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(contextDidSave(_:)), name: Notification.Name.NSManagedObjectContextDidSave, object: nil)
参考:https://medium.com/@marcosantadev/core-data-notifications-with-swift-acc8232a674e
但是,我同意@marci0907 的解决方案
【讨论】:
以上是关于使用 tableView.reloadData() 重新加载 TableView 的问题的主要内容,如果未能解决你的问题,请参考以下文章
如何让 tableView.reloadData() 与核心数据正常工作?
[tableView reloadData] 和 runloop
tableview.reloaddata() 在使用 coredata 时搜索栏取消按钮后不起作用
每次视图出现时 tableView.reloadData()