使用Swift中的Core Data在表视图中显示数据

时间:2015-11-11 14:50:31

标签: swift uitableview core-data nsfetchedresultscontroller

我在使用Swift中的Core Data在表格视图中显示分组的数据时遇到了一些麻烦。

我将使用一个例子说明问题。让我们假设三个类:订单,产品和服务。班级订单有一个属性" date"与产品和服务的多种关系。

对于每个订单,应创建一个部分以显示在特定日期订购的所有产品和服务。

使用NSFetchedResultsController,所有订单都根据atttribute日期获取。这提供了正确数量的部分。 但是,由于" numberOfRowsInSection"我在每个部分的单独行中显示所有产品和服务时遇到问题。是基于订单数量而不是产品和服务数量。

下面是说明我的问题的代码。希望任何人都可以帮助我找到正确的方向。

提前致谢,

杰拉德

import UIKit
import CoreData

class ExampleViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate {

@IBOutlet weak var tableView: UITableView!

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var fetchedResultController: NSFetchedResultsController = NSFetchedResultsController()

var orders = [Order]()

override func viewDidLoad() {
    super.viewDidLoad()
    fetchedResultController.delegate = self
    tableView.dataSource = self
    tableView.delegate = self

    fetchData()
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return fetchedResultController.sections?.count ?? 0
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let sectionInfo = fetchedResultController.sections![section] as NSFetchedResultsSectionInfo
    return sectionInfo.numberOfObjects
    // Unfortunatelly, this provides not the total number of products and services per section
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let textCellIdentifier = "ExampleTableViewCell"
    let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as! ExampleTableViewCell

    let order = orders[indexPath.row] // Data fetched using NSFetchedResultsController

    let products = order.products!.allObjects as! [Product] // Swift Array
    let services = order.services!.allObjects as! [Service] // Swift Array

    // Each product and each service should be displayed in separate rows. 
    // Instead, all products and services are displayed in a single row as below
    var displaytext = ""
    for product in products {
        displaytext += product.name! + "\n"
    }

    for service in services {
        displaytext += service.name! + "\n"
    }

    cell.orderLabel.text = displaytext // display text in ExampleTableViewCell

    return cell
}

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    if let sections = fetchedResultController.sections {
        let currentSection = sections[section]
        return currentSection.name
    }
    return nil
}


func orderFetchRequest() -> NSFetchRequest {
    let fetchRequest = NSFetchRequest(entityName: "Order")
    let sortDescriptor = NSSortDescriptor(key: "date", ascending: true)
    let predicate = NSPredicate(format: "date >= %@ AND date <= %@", startDate, endDate) // startDate and endData are defined elsewhere

    fetchRequest.sortDescriptors = [sortDescriptor]
    fetchRequest.predicate = predicate

    return fetchRequest
}

func fetchData() {
    let fetchRequest = orderFetchRequest()
    fetchedResultController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: "date", cacheName: nil)

    do {
        orders = try managedObjectContext.executeFetchRequest(fetchRequest) as! [Order]
    }
    catch let error as NSError {
        print("Could not fetch \(error), \(error.userInfo)")
    }

    do {
        try fetchedResultController.performFetch()
    }
    catch _ {
    }
}

}

1 个答案:

答案 0 :(得分:0)

正如Wain所说,FRC并没有多大帮助。 FRC有两个主要优点,除了普通的提取之外:它可以为您管理部分,并且可以通过其委托方法自动处理插入/删除/更新。第一个在您的情况下没用,因为您需要每个订单一个部分。第二个没有什么帮助,因为FRC只会观看一个实体进行更改,但您的表视图是由三个构建的。

尽管如此,我认为您可以使用FRC来实现某些效果。首先,不要打扰sectionNameKeyPath:您在Orders和表格视图部分之间有一对一的映射,因此您可以使用tableview&#39; s section作为索引。 FRC fetchedObjects确定每个部分的顺序。然后,可以通过将相关numberOrRowsInSection的{​​{1}}和products的计数相加来找到services。凌乱(可能很慢)的位是将表格视图的行映射到Orderproducts的正确元素。

services

可能有更简洁的方法对此进行编码;我不是斯威夫特的狂热爱好者。

如果您使用FRC委托方法,您至少可以根据需要监视新的/已删除的订单以及向电视添加/删除部分,并且您可以使用更新来重新加载相关部分。