将核心数据快速检索到 tableview 单元格中 [英] retrieving core data into tableview cells swift

查看:23
本文介绍了将核心数据快速检索到 tableview 单元格中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试简单地存储和检索 CoreData(我之前使用 swift 成功完成了这项工作).我的数据为零,但现在(不确定发生了什么变化)我没有收到错误,只是在 tableview 中没有显示任何内容.我不确定存储或检索对象是否有问题.我已经尽可能密切地关注我在另一个应用程序中是如何做到的,但似乎有一些基本的东西我没有得到.这是我所拥有的.

I am trying to simply store and retrieve CoreData (something that I've done successfully before with swift). I was getting a nil for data, but now (not sure what changed) I'm not getting an error, just nothing showing in the tableview. I'm not sure if it's a problem in storing or retrieving the object. I've followed how I did it in another app of mine as closely as possible, but there seems to be some fundamental thing that I'm not getting. Here's what I have.

我的模型:

import Foundation
import CoreData

@objc(DataModel)
class DataModel: NSManagedObject {

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

}

在我的 tableviewcontroller 中,我想从中保存数据的文本字段的静态单元格:

In my tableviewcontroller with static cells for text fields that I want to save data from:

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 中,我想检索在动态单元格中显示的数据:

And in my tableviewcontroller that I want to retrieve the data an show in dynamic cells:

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

}

对我可能在这里某处遗漏的概念的任何帮助将不胜感激!谢谢.

Any help on a concept I might have missed somewhere in here would be appreciated! Thanks.

更新:所以我重新编写了我的代码,以按照@Bluehound 的建议进行建模.但我仍然收到一个错误:不知道如何修复它.

Update: so I've redone my code to be modeled after @Bluehound 's suggestion. but I'm still getting an error: not sure how to fix it.

推荐答案

当使用核心数据和 tableview 时,你应该使用 NSFetchedResultsController.这实质上是从核心数据中检索数据并按部分和索引路径组织它,因此可以轻松地将其设置为 tableView 的数据源.这是一个符合 NSFetchedResultsControllerDelegate 的潜在 UITableViewController 的完整实现:​​

When using core data and a tableview, you should use NSFetchedResultsController. This essentially retrieves data from core data and organizes it by section and indexPath so it can easily be set as the data source of the tableView. Here is a complete implementation of a potential UITableViewController that conforms to NSFetchedResultsControllerDelegate:

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 项目.

这篇关于将核心数据快速检索到 tableview 单元格中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆