从TableViewCell中的UISwitch更新核心数据
我有一个绑定到一些Core Data
值的静态表,我不确定在这种情况下我将如何使用NSFetchedResultsController
,尽管我已经看到关于多推荐多少的讨论是。从TableViewCell中的UISwitch更新核心数据
我抓住我的Core Data
对象,它通过Segue
传递。
我也有一个设置为包含问题的模型,其中一个属性包含Core Data
值(这就是为什么我不认为我可以使用NSFetchedResultsController
,因为即使我的Core Data实体包含一些我需要的价值观,我不知道我需要一个完整的数据集)
self.surveyQuestion.append(SurveyQuestion(question: "Does the customer have a 'Proof of ownership'?", answer: coreDataEntity.isProofOfOwnership as Bool))
的问题是调查相关的诸如“你的财产X?”与映射到Core Data
值UiSwitch
:
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我需要它来更新核心数据值,并重新装载表,它挂接到一个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()
}
}
我可以明显地访问其中的切换触发位,但此类不知道的核心数据位什么的,我想使用的通知,但只是似乎有点乱...
当你创建你的细胞,传递到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()
你有一个如何传递参考的例子吗? – dyatesupnorth
对不起,我不明白,我的单元格定义中的下落?你的意思是类,即。SurveyQuestionTableViewCell:UITableViewCell还是在cellForRowAtIndexPath函数内部? – dyatesupnorth
我已更新答案 – Russell
尝试使用此代码:
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") }
但不应该SurveyQuestionTabelViewCell不知道任何关于核心数据对象,我认为这种事情是不好的做法? – dyatesupnorth
这里的另一个选项,使用共享实例
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
}
然后在任何c姑娘这需要这个数据模型
var dataModel = DataModelInstance.sharedInstance
我知道有访问那些谁只是永远不会使用单身,但它可以是一个更好的解决方案,以使这些属性提供需要的地方去
使用共享数据模型,您可以简单地将所有数据属性移出它们当前所在的类,并通过数据模型引用它们 - 然后,如果您在自定义单元类中具有相同的数据模型,则可以执行无论你在主视图中能做什么。为了使您的GUI和处理逻辑独立的,你可以把一切都在数据模型
dataModel.refreshTable()
,然后定义数据模型,把你的表视图的护理有关的功能 - 你可以目前所有的编辑内容保存到数据,并重新加载,而不必将任何逻辑放入单独的单元类中
看起来像一个更清洁的方法,虽然我是在这个项目的时刻,兔子洞有点太远了,是否有任何教程项目使用这种方法?就这样我可以看到一个项目将如何整体放在一起? – dyatesupnorth
看起来像你'\可能是正确的。我找不到任何包含单例和数据库的单个教程,但有很多关于如何实现单例的教程,我认为最新版本的swift可能已经简化了更多http:/ /codereview.stackexchange.com/questions/80246/swift-1-2-singleton-implementation – Russell
您必须在闭包中使用[unowned self] in
。见Apple's docs。这是如何完成的。另请参阅CoreDataKit,这是一款28星级github回购核心数据堆栈。它可以在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)!)
}
})
}
你是说,当你在桌子上的一排切换开关,要重新加载整个表?你有什么改变? – Russell
UISwitch被绑定到一个Core Data值,当它改变时它需要更新Core Data实体并重新加载表格,因为这些布尔值有一些额外的逻辑,例如当一个开关在表格上改变时,另一个行需要消失 – dyatesupnorth
好吧 - 我知道你理论上可以通过self.superview获得单元格的父类,但是你可能会更好地将对tableview的引用存储为自定义单元类的一部分! 我已经更新了我的答案,只是为了保持在一个地方 – Russell