Swift - 保存TableView中选中的复选标记

时间:2014-12-01 21:08:00

标签: ios uitableview swift multi-select

我对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
}    

和我的didSelectRowAtIndexPath

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)

}    

3 个答案:

答案 0 :(得分:1)

两件事:

cellForRowAtIndexPath:中的代码非常完美。它会使用listItems[indexPath.row]中的信息填充您单元格的文本和复选标记。但是在您的didSelectRowAtIndexPath:中,您永远不会更改listItems,以便cellForRowAtIndexPath:具有更新的数据,以便在重新加载时从中提取新行。因此,不要使用deselectRowAtIndexPath:,只需更新listItems数组,然后更新reloadRowsAtIndexPaths。 (老实说,我很困惑为什么它一直在为你工作,因为你在重新加载未更新的数据上。)以下是我推荐的内容:

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)

}

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

使用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)


    }

然后在我的func中加载保存列表项的初始数据数组,创建了一个变量savedValues,如下所示:

 var savedValues : String? = NSUserDefaults.standardUserDefaults().valueForKey("savedValues") as? String



    if(!(savedValues==nil))
    {
        var nsStr: NSString = savedValues!
        let array = nsStr.componentsSeparatedByString("  ");
        for val in array {
            listItems[val.integerValue].completed = true
        }
    }

当然,不要忘记在loadInitialData()

中致电viewDidLoad()

感谢所有帮助我的人:)