Ios Swift-保存在TableView中选择的复选标记

Ios Swift-保存在TableView中选择的复选标记,ios,uitableview,swift,multi-select,Ios,Uitableview,Swift,Multi Select,我是Swift的新手,我对TableView多选有疑问。我有多个选择,我可以用复选标记检查,类似于待办事项列表 当我检查项目时,我希望能够返回ListView并保存我的选择。 我假设保持保存状态的代码会在这里的某个地方?这是写入单个单元格项复选标记的类: class ListItem: NSObject { let itemName: String var completed: Bool init(itemName: String, completed: Boo

我是Swift的新手,我对TableView多选有疑问。我有多个选择,我可以用复选标记检查,类似于待办事项列表

当我检查项目时,我希望能够返回ListView并保存我的选择。 我假设保持保存状态的代码会在这里的某个地方?这是写入单个单元格项复选标记的类:

    class ListItem: NSObject {
    let itemName: String
    var completed: Bool

    init(itemName: String, completed: Bool = false)
    {
        self.itemName = itemName
        self.completed = completed
    }
}   
有人能告诉我怎么做吗

这是cellForRowAtIndexPath

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let tempCell = tableView.dequeueReusableCellWithIdentifier("ListPrototypeCell") as UITableViewCell
    let listItem = listItems[indexPath.row]

    // Downcast from UILabel? to UILabel
    let cell = tempCell.textLabel as UILabel!
    cell.text = listItem.itemName

    if (listItem.completed)
    {
        tempCell.accessoryType = UITableViewCellAccessoryType.Checkmark;
    }
    else
    {
        tempCell.accessoryType = UITableViewCellAccessoryType.None;
    }

    return tempCell
}    
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRowAtIndexPath(indexPath, animated: false)

    let tappedItem = listItems[indexPath.row] as ListItem
    tappedItem.completed = !tappedItem.completed

    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)

}    
我的孩子选择了一条小路

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let tempCell = tableView.dequeueReusableCellWithIdentifier("ListPrototypeCell") as UITableViewCell
    let listItem = listItems[indexPath.row]

    // Downcast from UILabel? to UILabel
    let cell = tempCell.textLabel as UILabel!
    cell.text = listItem.itemName

    if (listItem.completed)
    {
        tempCell.accessoryType = UITableViewCellAccessoryType.Checkmark;
    }
    else
    {
        tempCell.accessoryType = UITableViewCellAccessoryType.None;
    }

    return tempCell
}    
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRowAtIndexPath(indexPath, animated: false)

    let tappedItem = listItems[indexPath.row] as ListItem
    tappedItem.completed = !tappedItem.completed

    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)

}    

我假定您有一个表示模型数据(表视图的内容)的ListItem数组。然后,要在运行中的应用程序之外保留此内容,您可以将其保存到NSUserDefaults或文件中。为此,您需要一种序列化ListItem的方法。通常的方法是让ListItem采用NSCoding协议,并实现
encodeWithCoder:
init(coder:)
来使用NSKeyedArchiver和NSKeyedUnarchiver(这些方法中的“编码器”)将ListItem对象转换为NSData,反之亦然。完成此操作后,可以使用NSKeyedArchiver和NSKeyedNarchiver直接序列化ListItem数组。

两件事:

您在
cellforrowatinexpath:
中的代码非常完美。它从
listItems[indexath.row]
获取信息,以填充单元格的文本和复选标记。但是,在您的
didSelectRowAtIndexPath:
中,您永远不会更改
listItems
,从而使
cellForRowAtIndexPath:
具有更新的数据,以便在重新加载时从中提取新行。因此,不要使用
取消行索引路径:
,只需更新
列表项
数组,然后
重新加载行索引路径
。(老实说,我不明白为什么到目前为止它对您有效,因为您正在调用重新加载未更新的数据。)以下是我的建议:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    let tappedItem = listItems[indexPath.row] as ListItem
    tappedItem.completed = !tappedItem.completed

    // Store the updated tappedItem back at the listItems index
    listItems[indexPath.row] = tappedItem

    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)

}

其次,只要该数组存储在未被释放的视图控制器中,就不会丢失该数据,并且可以重新填充该表。但是,如果它存储在正在解除分配的视图控制器(或表视图控制器)中,您可能希望将其存储在程序的其他位置。

使用NSUserDefaults稍微解决了这种混合和匹配问题 下面是:

在“我的弹出式表格/列表视图”的导航栏中创建了一个按钮,该按钮的功能如下:

 //create a done button in the navigation bar
    var done = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: Selector("doneBtn"))
    self.navigationItem.rightBarButtonItem = done

}

//This is the "Done" button functionality

func doneBtn()
{

    var saveString = ""

    for var i=0; i<listItems.count; i++
    {
        let listItem = listItems[i]
        if (listItem.completed)
        {
            saveString = saveString + "  " + "\(i)"
        }
    }

    saveString = saveString.stringByTrimmingCharactersInSet(NSCharacterSet .whitespaceAndNewlineCharacterSet())

    NSUserDefaults.standardUserDefaults().setValue(saveString, forKey: "savedValues")
    NSUserDefaults.standardUserDefaults().synchronize()


    self.navigationController?.dismissViewControllerAnimated(true, completion: nil)


    }
当然,不要忘记在
viewDidLoad()中调用
loadInitialData()


感谢所有帮助我的人:)

当你说“拯救”是什么意思?您是否需要在应用程序打开之间保留您的选择?是否要取消分配包含表视图的视图控制器,并需要重新创建其内容?如何存储总体数据?应该存储完成状态,然后在显示表时检查是否应该检查。I Lindsey,我的意思是我想选择项目,并在返回表视图时查看我的复选标记。至于释放视图控制器并重新创建其内容,我将只对应用程序的一个特定部分使用tableview,因此我不需要重用其任何内容。这有意义吗?是的,那么只要你的视图控制器没有被解除分配,你就不会丢失任何数据,所以不需要保存。为了回答您最初的问题,数据实际上不应该在自定义单元格中访问,而应该在与tableview相同的视图控制器中访问。。。如果您有任何问题,我的猜测是它要么与
cellForRowAtIndexPath
中的代码有关,要么与数据结构有关(比如必须设置检查布尔值的类数组)在同一个视图控制器中。@LyndseyScott流程是,我有一个UIViewController,带有一个按钮,可以通过弹出按钮调用UITableView。我可以用复选标记进行选择,但当我再次单击按钮时,它们就会消失。我是否需要对核心数据功能进行编程,以使选中标记保持其选中模式?下面是一个简单Person对象的示例-与ListItem对象没有太大区别:嗨,Matt,我不确定如何以数组格式调用它。这是怎么采用的?这就是我对encodeWithCoder所做的:
required init(coder-aDecoder:NSCoder){super.init(coder:aDecoder)}
@NatashaJulain你说过你不需要在应用程序之外保存数据(即在应用程序启动之间),所以这是不必要的。早上好:)我已经按照你的建议更新了我的代码。清理了构建,运行了代码,但它没有达到我的要求:(我选择的项目仍然取消选择。@NatashaJulain我怀疑这与重新加载从一开始就不适用于您有关……就像我说的“我不明白为什么到目前为止它适用于您,因为您正在对未更新的数据调用重新加载。”您的表最初依赖于
取消行索引路径:
进行更改。我会仔细考虑一下,稍后再与您联系……但我很好奇……当您将
tableView.reloadsatindexpaths(…
替换为
tableView.reloadData()时会发生什么情况
?那么它能工作吗?我已经解决了!我发布了我的答案:)但是使用了
NSUserDefaults
::你可以看看我做了什么。谢谢你宝贵的时间来帮助。@LyndseyScott在上面的例子中什么是listItems。请解释一下。