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

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

问题描述

我试图简单地存储和检索CoreData(我在swift之前做过的事情)。我得到一个零的数据,但现在(不知道什么改变)我没有得到一个错误,只是没有显示在tableview。我不知道这是否存储或检索对象的问题。我跟着我是如何在我的另一个应用程序,尽可能接近,但似乎有一些基本的事情,我没有得到。这是我的。



我的模型:

  import Foundation 
import CoreData

@objc(DataModel)
class DataModel:NSManagedObject {

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

}

我的tableviewcontroller和我想要保存数据的文本字段的静态单元格:

  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()
//处理可以重新创建的任何资源。
}


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

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

b $ b 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 )
}



在我的tableviewcontroller中,我想检索数据cell:

  class ItemListTableViewController:UITableViewController {

var items:Array< AnyObject> = []

覆盖func viewDidLoad(){
super.viewDidLoad()
}



override func didReceiveMemoryWarning (){
super.didReceiveMemoryWarning()
//处理可以重新创建的任何资源。
}

// MARK: - 表视图数据源

override func numberOfSectionsInTableView(tableView:UITableView) - > Int {
// #warning潜在地不完整的方法实现。
//返回节的数量。
return 1
}

override func tableView(tableView:UITableView,numberOfRowsInSection section:Int) - > Int {
// #warning不完整的方法实现。
//返回节中的行数。
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

}
pre>

任何帮助一个概念我可能错过了在这里的某个地方将不胜感激!谢谢。



更新:所以我重新编写我的代码,以@Bluehound的建议。但我仍然得到一个错误:不知道如何解决它。

解决方案

当使用核心数据和tableview时,应该使用 NSFetchedResultsController 。这基本上从核心数据检索数据,并通过section和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数据源和委托函数
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

如果let cellContact = fetchedResultsController?.objectAtIndexPath(indexPath)as?员工{
cell.textLabel?.text =\(cellContact.nameLast),\(cellContact.nameFirst)

}

$ b b返回单元
}

// MARK:NSFetchedResultsController委托函数
func controller(controller:NSFetchedResultsController,didChangeSection sectionInfo:NSFetchedResultsSectionInfo,atIndex sectionIndex:Int,forChangeType type:NSFetchedResultsChangeType){

开关类型{
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){
如果editingStyle == .Delete {
}

切换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 (object:indexPath!),withRowAnimation:UITableViewRowAnimation.Fade)
tableView.insertRowsAtIndexPaths(NSArray(object:newIndexPath!),withRowAnimation:UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Update:
tableView.cellForRowAtIndexPath(indexPath!)
break
默认值:
break
}
}

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

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

查看示例GitHub项目。


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.

My model:

import Foundation
import CoreData

@objc(DataModel)
class DataModel: NSManagedObject {

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

}

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)
}

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.

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.

解决方案

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()
    }
}

See a sample GitHub project here.

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

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