将核心数据检索到TableView单元格中,Swift

10

我试图简单地存储和检索CoreData(这是我以前使用swift成功完成的事情)。我之前得到的是数据为空,但现在(不确定发生了什么变化)我没有得到错误,只是在表格视图中没有显示任何内容。我不确定是在存储还是检索对象方面出了问题。我尽可能地按照我在另一个应用程序中的做法来实现,但似乎有一些基本的东西我没有掌握。以下是我的代码:

我的模型:

import Foundation
import CoreData

@objc(DataModel)
class DataModel: NSManagedObject {

@NSManaged var itemName: String
@NSManaged var quantity: NSNumber
@NSManaged var price: NSNumber

}

在我的表格视图控制器中,使用静态单元格来保存我想要保存数据的文本字段:

import UIKit
import CoreData

class NewItemTableViewController: UITableViewController {

@IBOutlet weak var itemNameTextField: UITextField!
@IBOutlet weak var itemPriceTextField: UITextField!
@IBOutlet weak var itemQuantityTextField: UITextField!


override func viewDidLoad() {
    super.viewDidLoad()

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


@IBAction func saveButton(sender: AnyObject) {
    //CoreData
    let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
    let managedContext : NSManagedObjectContext = appDelegate.managedObjectContext!
    let entity =  NSEntityDescription.entityForName("Item", inManagedObjectContext: managedContext)

    var newItem = DataModel(entity: entity!, insertIntoManagedObjectContext: managedContext)


    newItem.itemName = itemNameTextField.text
    //newItem.price = itemPriceTextField.text
    //newItem.quantity = itemQuantityTextField
    managedContext.save(nil)

    self.navigationController?.popToRootViewControllerAnimated(true)


}
@IBAction func cancelButton(sender: AnyObject) {
    self.navigationController?.popToRootViewControllerAnimated(true)
}

而在我的tableviewcontroller中,我希望检索数据并在动态单元格中显示:

class ItemListTableViewController: UITableViewController {

var items : Array<AnyObject> = []

override func viewDidLoad() {
    super.viewDidLoad()
}



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete method implementation.
    // Return the number of rows in the section.
    return items.count
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let CellID: NSString = "cell"
    var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(CellID) as UITableViewCell
    var data: NSManagedObject = items[indexPath.row] as NSManagedObject


    var itemName = data.valueForKey("itemName") as String
    var price = data.valueForKey("price") as NSNumber
    var quantity = data.valueForKey("quantity") as NSNumber


    cell.textLabel!.text! = "\(itemName)"
    cell.detailTextLabel!.text! = "Price: \(price) - Quantity: \(quantity)"

    return cell

}

如果我在这里错过了任何概念,希望能得到帮助!谢谢。

更新:所以我已经按照 @Bluehound 的建议重新编写了代码。但是我仍然遇到错误:不确定如何解决。 enter image description here


你的 items 数组是如何以及在哪里被填充的? - pbasdf
1个回答

18

在使用核心数据和表格视图时,您应该使用NSFetchedResultsController。这实质上从核心数据中检索数据,并按部分和indexPath进行组织,以便可以轻松地将其设置为tableView的数据源。以下是一个完整的可能符合NSFetchedResultsControllerDelegate的UITableViewController实现:

import Foundation
import UIKit
import CoreData


class HomeViewController: UITableViewController, NSFetchedResultsControllerDelegate {

    let managedObjectContext: NSManagedObjectContext? = (UIApplication.sharedApplication().delegate as? AppDelegate)?.managedObjectContext

    var fetchedResultsController: NSFetchedResultsController?

    override func viewDidLoad() {
        super.viewDidLoad()

        fetchedResultsController = NSFetchedResultsController(fetchRequest: allEmployeesFetchRequest(), managedObjectContext: managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil)
        fetchedResultsController?.delegate = self
        fetchedResultsController?.performFetch(nil)


    }

    func allEmployeesFetchRequest() -> NSFetchRequest {

        var fetchRequest = NSFetchRequest(entityName: "Employee")
        let sortDescriptor = NSSortDescriptor(key: "nameLast", ascending: true)

        fetchRequest.predicate = nil
        fetchRequest.sortDescriptors = [sortDescriptor]
        fetchRequest.fetchBatchSize = 20

        return fetchRequest
    }

    //MARK: UITableView Data Source and Delegate Functions
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return fetchedResultsController?.sections?.count ?? 0
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return fetchedResultsController?.sections?[section].numberOfObjects ?? 0
    }

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

        if let cellContact = fetchedResultsController?.objectAtIndexPath(indexPath) as? Employee {
            cell.textLabel?.text = "\(cellContact.nameLast), \(cellContact.nameFirst)"

        }


        return cell
    }

    //MARK: NSFetchedResultsController Delegate Functions
    func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {

        switch type {
        case NSFetchedResultsChangeType.Insert:
            tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade)
            break
        case NSFetchedResultsChangeType.Delete:
            tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade)
            break
        case NSFetchedResultsChangeType.Move:
            break
        case NSFetchedResultsChangeType.Update:
            break
        default:
            break
        }
    }

    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
        }

        switch editingStyle {
        case .Delete:
            managedObjectContext?.deleteObject(fetchedResultsController?.objectAtIndexPath(indexPath) as Employee)
            managedObjectContext?.save(nil)
        case .Insert:
            break
        case .None:
            break
        }

    }

    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {

        switch type {
        case NSFetchedResultsChangeType.Insert:
            tableView.insertRowsAtIndexPaths(NSArray(object: newIndexPath!), withRowAnimation: UITableViewRowAnimation.Fade)
            break
        case NSFetchedResultsChangeType.Delete:
            tableView.deleteRowsAtIndexPaths(NSArray(object: indexPath!), withRowAnimation: UITableViewRowAnimation.Fade)
            break
        case NSFetchedResultsChangeType.Move:
            tableView.deleteRowsAtIndexPaths(NSArray(object: indexPath!), withRowAnimation: UITableViewRowAnimation.Fade)
            tableView.insertRowsAtIndexPaths(NSArray(object: newIndexPath!), withRowAnimation: UITableViewRowAnimation.Fade)
            break
        case NSFetchedResultsChangeType.Update:
            tableView.cellForRowAtIndexPath(indexPath!)
            break
        default:
            break
        }
    }

    func controllerWillChangeContent(controller: NSFetchedResultsController) {
        tableView.beginUpdates()
    }

    func controllerDidChangeContent(controller: NSFetchedResultsController) {
        tableView.endUpdates()
    }
}

在这里查看一个GitHub项目的示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接