CoreData 与 tableView 部分

Posted

技术标签:

【中文标题】CoreData 与 tableView 部分【英文标题】:CoreData with tableView Sections 【发布时间】:2020-10-10 14:53:14 【问题描述】:

我有 CoreData 模型:

我尝试使用 fetchResultsController 来显示部分和行。部分应该来自 Category 实体,而行应该来自 Items 实体。我怎样才能做到这一点?

我使用代码:

override func numberOfSections(in tableView: UITableView) -> Int 
    return fetchResultsController?.sections?.count ?? 1
    

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    let sectionInfo = fetchResultsController.sections![section]
    return sectionInfo.numberOfObjects


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ItemsTableViewCell


    if let person = fetchResultsController?.object(at: indexPath)  
        cell.textLabel?.text = person.name
    


    return cell

但使用此代码,我只能获得类别名称。但我想显示与特殊类别相关的项目。我应该改变什么

if let person = fetchResultsController?.object(at: indexPath)  
    cell.textLabel?.text = person.name

显示特殊类别的项目?

我的 fetchResultsController 配置代码:

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


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

  switch type 
  case .insert: guard let indexPath = newIndexPath else  break 
  tableView.insertRows(at: [indexPath], with: .fade)
  case .delete: guard let indexPath = indexPath else  break 
    tableView.deleteRows(at: [indexPath], with: .fade)
  case .update: guard let indexPath = indexPath else  break 
    tableView.reloadRows(at: [indexPath], with: .fade)
  default:
    tableView.reloadData()
  
    categories = controller.fetchedObjects as! [Category]


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

还有:

var fetchResultsController: NSFetchedResultsController<Category>!
    let request: NSFetchRequest<Category> = Category.fetchRequest()
    request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
    fetchResultsController = NSFetchedResultsController<Category>(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
    try? fetchResultsController?.performFetch()
    fetchResultsController?.delegate = self
    tableView.reloadData()

【问题讨论】:

请显示配置您的 fetchedresultscontroller 的代码。这就是问题所在。 我添加了代码。 谢谢,但我的意思是您创建 frc 的代码。 我添加了代码。 【参考方案1】:

您需要将 frc 基于 Item 实体,并使用 sectionNameKeyPath 引用 Category 名称:

var fetchResultsController: NSFetchedResultsController<Item>!
    let request: NSFetchRequest<Item> = Item.fetchRequest()
    request.sortDescriptors = [NSSortDescriptor(key: "list.name", ascending: true)]
    fetchResultsController = NSFetchedResultsController<Item>(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: “list.name”, cacheName: nil)
    try? fetchResultsController?.performFetch()
    fetchResultsController?.delegate = self
    tableView.reloadData()

【讨论】:

以上是关于CoreData 与 tableView 部分的主要内容,如果未能解决你的问题,请参考以下文章

如何在 coredata/NSManagedObject 模型数据更改与应用程序用户界面之间进行紧密耦合?

无法将 tableView.deleteRowsAtIndexPaths 与 coreData 一起使用

使用 NSFetchedResultsController 在 TableView 上显示的元素列表与底层 CoreData 实体不匹配

在 CoreData 中更新项目不会刷新 tableView

调用多个CoreData键值进行tableview单元格显示

Swift 3. 使用 Core Data 隐藏一个空的 tableView