从TableViewCell内的UISwitch更新核心数据

时间:2016-01-21 14:29:54

标签: ios swift core-data uiswitch

我有一个绑定到某些Core Data值的静态表,我不知道在这个例子中我将如何使用NSFetchedResultsController,尽管我已经看到有关它的建议是多少

我抓住通过Core Data传递的Segue对象。

我还有一个设置为包含问题的模型,其中一个属性包含Core Data值(这就是为什么我认为我不能使用NSFetchedResultsController,因为即使我的核心数据实体包含我需要的一些值,我不确定我是否需要完整的数据集

self.surveyQuestion.append(SurveyQuestion(question: "Does the customer have a 'Proof of ownership'?", answer: coreDataEntity.isProofOfOwnership as Bool))

问题是调查相关的问题,例如“你的房产X?” UiSwitch映射到Core Data值:

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

    // Configure the cell...
    let cell : SurveyQuestionTableViewCell = tableView.dequeueReusableCellWithIdentifier("SurveyQuestionCell") as! SurveyQuestionTableViewCell

    cell.lblQuestion.textColor = UIColor.grayColor()

    let surveyQuestion = self.surveyQuestion[indexPath.row]
    cell.lblQuestion.text = surveyQuestion.question
    cell.toggQuestion.on = surveyQuestion.answer
    if cell.toggQuestion.on {
                   cell.lblQuestion.textColor = UIColor.blackColor()
    cell.accessoryType = .DetailDisclosureButton
    }

    return cell
}

现在,当我点击UISwitch时,我需要它来更新Core Data值,并重新加载表,它连接到CustomTableViewCell,如下所示:

*编辑 - 几乎让这件事有效!继承我的UITableViewCell课程

 class SurveyQuestionTableViewCell: UITableViewCell {


    let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

    @IBOutlet weak var lblQuestion: UILabel!

    @IBOutlet weak var toggQuestion: UISwitch!
    var surveyQuestionReference : SurveyQuestion?
    var tableViewReference : UITableView?

    @IBAction func toggledQuestion(sender: AnyObject) {
        let tempContext: NSManagedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
        tempContext.parentContext = self.managedObjectContext

        tempContext.performBlock({
            let entityName = "CoreDataEntity"
            let request = NSFetchRequest(entityName: entityName)
            request.predicate = NSPredicate(format: "id = %@", self.surveyQuestionReference!.id)
            do {

                let results = try tempContext.executeFetchRequest(request) as? [NSManagedObject]

                if results!.count > 0{

                        if let moc = self.managedObjectContext{
                            moc.performBlockAndWait({



                                for result in results!{
                                   result.setValue(self.toggQuestion.on, forKey: (self.surveyQuestionReference?.property)!)
                                }



                            })





                    }
                }
                do {
                    try tempContext.save()

                    //completion(finished: true)
                } catch let error {
                    print(error)
                }
            }catch{
                print("error")
            }

        })
        print(sender)
        dispatch_async(dispatch_get_main_queue()) {
          self.tableViewReference!.reloadData()

        }

        }

我显然可以访问触发切换的位,但是这个类对Core Data位一无所知,我正在考虑使用通知,但这看起来有点混乱......

4 个答案:

答案 0 :(得分:1)

当您创建单元格时,传入对coredata对象的引用,以及tableView本身并将它们存储为SurveyQuestionTableViewCell的属性,然后您可以在setSelected()中执行所需的一切

在自定义单元格类中,添加问题的属性

class SurveyQuestionTableViewCell: UITableViewCell {

    @IBOutlet weak var lblQuestion: UILabel!

    @IBOutlet weak var toggQuestion: UISwitch!

    var surveyQuestionReference : SurveyQuestionType
    vat tableViewReference : UITableView
    ...

然后在创建单元格

后的cellForRowAtIndexPath中
cell.surveyQuestionReference = surveyQuestion
cell.tableViewReference = tableView

其中SurveyQuestionType是您之前定义的任何内容

在setSelected中,您可以使用那些存储的属性

surveyQuestionReference = self.toggQuestion.on
tableViewReference.reloadData()

答案 1 :(得分:1)

这是另一种选择,使用共享实例

import Foundation
import MapKit
import CoreData


class DataModelInstance : NSObject, NSCoding
{
    var appDelegate         : AppDelegate?
    var managedContext      : NSManagedObjectContext?
    var persistentStoreCoordinator         : NSPersistentStoreCoordinator?

    // plus whatever else you need

class var sharedInstance : DataModelInstance
{
    struct Singleton
    {
        static let instance = DataModelInstance()
    }


    return Singleton.instance
}

然后在任何需要访问此数据模型的类中

var dataModel = DataModelInstance.sharedInstance

我知道有些人刚刚使用过单身人士,但在需要的地方提供这些属性可能是一个更优雅的解决方案

使用共享数据模型,您可以简单地将所有数据属性移出其当前所在的类,并通过数据模型引用它们 - 如果您在自定义单元类中具有相同的数据模型,则可以在主视图中执行任何操作。为了使GUI和处理逻辑分离,您可以将所有内容放在数据模型中

dataModel.refreshTable()

然后在数据模型中定义一个处理表视图的函数 - 您可以将所有当前编辑保存到数据中并重新加载,而不必将任何逻辑放在单个单元类中

答案 2 :(得分:0)

更新核心数据中的任何记录尝试使用此代码:

let managedObjectContext:NSManagedObjectContext=(UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!
let req=NSFetchRequest(entityName: "Entity Name")
req.returnsObjectsAsFaults=false
let result:NSArray=try! managedObjectContext.executeFetchRequest(req)

if result.count>0{

let res=result[Int(indexPath.row!]as! NSManagedObject
res.setValue("The Value", forKey: "Key Name")
 do {
     try managedObjectContext.save()
     } catch _ { print("Update Unsuccessful") }

答案 3 :(得分:0)

您必须在闭包内使用[unowned self] in。见Apple's docs。这就是它的完成方式。另请参阅CoreDataKit,一个28星级的github repo核心数据堆栈。它可以在cocoapods上使用,老实说,为什么不把这样的东西放到你的应用程序中而不用担心"无主的自我"和其他哲学的绕口令,嗯?

if let moc = self.managedObjectContext{
                        moc.performBlockAndWait({

                            /* In here we are in a closure (Swift version of a block), so "self" is problematic. Use unowned self instead (in objective c you'd have to do weak self). */
                            [unowned self] in
                            for result in results!{
                               result.setValue(self.toggQuestion.on, 
                                      forKey: (self.surveyQuestionReference?.property)!)
                            }


                        })
                    }