Ios 如何在Swift核心数据应用程序的UITableView中保存选中标记状态
我已经使用核心数据实现了一个列表应用程序。我想做的是添加复选标记,这样用户就可以单击单元格,并显示一个勾号以显示它已完成 我不知道如何保存这些复选标记,因此当应用程序关闭、打开或重新启动时,该复选标记仍将存在于特定单元格中。我应该使用CoreData还是NSUserDefaults来实现这一点?我将如何使用这些工具来实现它 以下是迄今为止的代码: CellForRowatinex:Ios 如何在Swift核心数据应用程序的UITableView中保存选中标记状态,ios,swift,uitableview,core-data,nsuserdefaults,Ios,Swift,Uitableview,Core Data,Nsuserdefaults,我已经使用核心数据实现了一个列表应用程序。我想做的是添加复选标记,这样用户就可以单击单元格,并显示一个勾号以显示它已完成 我不知道如何保存这些复选标记,因此当应用程序关闭、打开或重新启动时,该复选标记仍将存在于特定单元格中。我应该使用CoreData还是NSUserDefaults来实现这一点?我将如何使用这些工具来实现它 以下是迄今为止的代码: CellForRowatinex: override func tableView(tableView: UITableView, cellForRo
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! as UITableViewCell
let item = Items[indexPath.row]
cell.textLabel?.item = task.valueForKey("item") as? String
return cell
}
DIDSelectRowatinex:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedRow:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
if selectedRow.accessoryType == UITableViewCellAccessoryType.None {
selectedRow.accessoryType = UITableViewCellAccessoryType.Checkmark
selectedRow.tintColor = UIColor.greenColor()
} else {
selectedRow.accessoryType = UITableViewCellAccessoryType.None
}
}
任何帮助都将不胜感激。您需要在数据模型(核心数据对象)而不是单元格中跟踪完成状态。如您所发现的,单元格将被重复使用,并且单元格不会被持久化,因此不会保存复选标记状态 我会用这样的方式:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let taskObject=self.listItems[indexPath.row]
var taskStatus = taskObject.valueForKey("completed") as? Bool ?? false
taskObject.setValue(!taskStatus,forKey:"completed") // Toggle completed status
do {
try managedContext.save()
} catch let error as NSError {
print("Cannot save object: \(error), \(error.localizedDescription)")
}
tableView.deselectRowAtIndexPath(indexPath,animated:false)
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}
然后,在cellforrowatinexpath
中,可以适当地渲染行:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("listCell") as! UITableViewCell
let task = listItems[indexPath.row]
let taskStatus = task.valueForKey("completed") as! Bool
cell.textLabel?.text = task.valueForKey("task") as? String
var accessoryType=UITableViewCellAccessoryType.None
var tintColor = UIColor.clearColor()
if (taskStatus) {
accessoryType=UITableViewCellAccessoryType.Checkmark
tintColor = UIColor.greenColor()
}
cell.accessoryType=accessoryType
cell.tintColor = tintColor
return cell
}
您需要在数据模型(核心数据对象)而不是单元格中跟踪完成状态。如您所发现的,单元格将被重复使用,并且单元格不会被持久化,因此不会保存复选标记状态 我会用这样的方式:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let taskObject=self.listItems[indexPath.row]
var taskStatus = taskObject.valueForKey("completed") as? Bool ?? false
taskObject.setValue(!taskStatus,forKey:"completed") // Toggle completed status
do {
try managedContext.save()
} catch let error as NSError {
print("Cannot save object: \(error), \(error.localizedDescription)")
}
tableView.deselectRowAtIndexPath(indexPath,animated:false)
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}
然后,在cellforrowatinexpath
中,可以适当地渲染行:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("listCell") as! UITableViewCell
let task = listItems[indexPath.row]
let taskStatus = task.valueForKey("completed") as! Bool
cell.textLabel?.text = task.valueForKey("task") as? String
var accessoryType=UITableViewCellAccessoryType.None
var tintColor = UIColor.clearColor()
if (taskStatus) {
accessoryType=UITableViewCellAccessoryType.Checkmark
tintColor = UIColor.greenColor()
}
cell.accessoryType=accessoryType
cell.tintColor = tintColor
return cell
}
您的核心数据实体需要一个
已完成的属性。任务完成后,将其设置为true并保存对象。使用此属性的值确定是否应在cellforrowatinexpath
中的给定行中添加复选标记。好的,我现在在核心数据实体中添加了一个名为“completed”的属性,并将其设置为boolean,让我直截了当地说,我是否在didSelectRowAtIndex方法中将已完成的任务设置为true?是的。在该方法中,您将其设置为true(如果它已经为true并且您希望支持切换功能,则可能为false),然后保存对象。在该方法中,您可以添加复选标记,在cellForRowAtIndexPath中,您也可以选择completed并将附件视图设置为复选标记或none(视情况而定),以便在didSelectRow方法中使用类似“selectedRow.setValue(true,forKey:“completed”)”的内容?在代码“”中,如果在我的上述代码中selectedRow.accessoryType==UITableViewCellAccessoryType.None{}“”?Not selectedRow,则使用indexPath中的行值从listItems
获取NSManagedObject,您的核心数据实体需要一个completed
Arribute。任务完成后,将其设置为true并保存对象。使用此属性的值确定是否应在cellforrowatinexpath
中的给定行中添加复选标记。好的,我现在在核心数据实体中添加了一个名为“completed”的属性,并将其设置为boolean,让我直截了当地说,我是否在didSelectRowAtIndex方法中将已完成的任务设置为true?是的。在该方法中,您将其设置为true(如果它已经为true并且您希望支持切换功能,则可能为false),然后保存对象。在该方法中,您可以添加复选标记,在cellForRowAtIndexPath中,您也可以选择completed并将附件视图设置为复选标记或none(视情况而定),以便在didSelectRow方法中使用类似“selectedRow.setValue(true,forKey:“completed”)”的内容?如果代码“”中的selectedRow.accessoryType==UITableViewCellAccessoryType.None{}在我的上述代码中?未selectedRow,您可以使用indexPath中的行值从listItems
获取NSManagedObject,谢谢您的时间,但我在“let taskStatus=task[“completed”]as”行中收到了两个“type”NSManagedObjects“has no subscription members”错误!“CellForRow”中的Bool'和“var taskStatus=taskObject[“completed”]为!“DidSelect”中的Bool?对不起。我是凭记忆打字的。您可以使用valueForKey[“completed”]
和setValue(,forKey:)
但是如果您使用Xcode为您生成NSManagedObject子类,那么使用核心数据要容易得多。我会在didSelect
中使用setValue(,forKey:)
和cellForRow
中使用valueForKey
?很抱歉,我不熟悉核心数据,我想这是一个帮助我学习的入门项目,如果更容易,您是否能够使用valueForKey
和setValue
更新代码?创建新任务时,您应该将此值初始化为false
。哪一行通过nil异常?它是让taskStatus=task.valueForKey(“已完成”)作为!Bool
line inCellForRow
谢谢您的时间,但我收到了两个错误,分别是“类型”NSManagedObjects“没有订阅成员”和“行”let taskStatus=task[“已完成”]as!“CellForRow”中的Bool'和“var taskStatus=taskObject[“completed”]为!“DidSelect”中的Bool?对不起。我是凭记忆打字的。您可以使用valueForKey[“completed”]
和setValue(,forKey:)
但是如果您使用Xcode为您生成NSManagedObject子类,那么使用核心数据要容易得多。我会在didSelect
中使用setValue(,forKey:)
和cellForRow
中使用valueForKey
?很抱歉,我不熟悉核心数据,我想这是一个帮助我学习的入门项目,如果更容易,您是否能够使用valueForKey
和setValue
更新代码?创建新任务时,您应该将此值初始化为false
。哪一行通过nil异常?它是让taskStatus=task.valueForKey(“已完成”)作为!Bool
行在CellForRow