Ios 如何在单元格中保存复选标记附件

Ios 如何在单元格中保存复选标记附件,ios,swift,uitableview,Ios,Swift,Uitableview,正在尝试开发检查表应用程序,但在尝试保存检查标记状态时被卡住了一段时间。当我离开tableView并返回时,所有保存的复选标记都会被删除。我已经导入了UKIT,然后定义了类 这是我的密码: var PreDefinedTasks = ["1", "2", "3", "4"] // MARK: - Table view data source override func tableView(_ tableView: UITableView, didSelectRowAt indexPath:

正在尝试开发检查表应用程序,但在尝试保存检查标记状态时被卡住了一段时间。当我离开tableView并返回时,所有保存的复选标记都会被删除。我已经导入了UKIT,然后定义了类

这是我的密码:

var PreDefinedTasks = ["1", "2", "3", "4"]

// MARK: - Table view data source

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)

    if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
        if cell.accessoryType == .checkmark{
            cell.accessoryType = .none
        }
        else{
            cell.accessoryType = .checkmark
        }
    }
}

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return PreDefinedTasks.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "List1", for: indexPath)

    cell.textLabel?.text = PreDefinedTasks[indexPath.row]

    return cell
}

我已经研究过NSCoder作为解决方案,但似乎无法让它正常工作。感谢您的帮助

您可以根据在tableView行上选择的复选标记将indexpath保存到数组中。

下面是我将如何操作的,如果您遵循整个解决方案,即使应用程序关闭,它也会保存

按如下方式从类型Bool生成一个数组:
var checkmarks=[Int:Bool]()

然后,在cellForRow函数中,添加以下内容:

if checkmarks[indexPath.row] != nil {
    cell.accessoryType = checkmarks[indexPath.row] ? .checkmark : .none
} else {
    checkmarks[indexPath.row] = false
    cell.accessoryType = .none
}
if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
    if cell.accessoryType == .checkmark{
        cell.accessoryType = .none
        checkmarks[indexPath.row] = false
    }
    else{
        cell.accessoryType = .checkmark
        checkmarks[indexPath.row] = true
    }
}
UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: checkmarks), forKey: "checkmarks")
UserDefaults.standard.synchronize()
if let checks = UserDefaults.standard.value(forKey: "checkmarks") as? NSData {
    checkmarks = NSKeyedUnarchiver.unarchiveObject(with: checks as Data) as! [Int : Bool]
}
在didSelectRow函数中,添加以下内容:

if checkmarks[indexPath.row] != nil {
    cell.accessoryType = checkmarks[indexPath.row] ? .checkmark : .none
} else {
    checkmarks[indexPath.row] = false
    cell.accessoryType = .none
}
if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
    if cell.accessoryType == .checkmark{
        cell.accessoryType = .none
        checkmarks[indexPath.row] = false
    }
    else{
        cell.accessoryType = .checkmark
        checkmarks[indexPath.row] = true
    }
}
UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: checkmarks), forKey: "checkmarks")
UserDefaults.standard.synchronize()
if let checks = UserDefaults.standard.value(forKey: "checkmarks") as? NSData {
    checkmarks = NSKeyedUnarchiver.unarchiveObject(with: checks as Data) as! [Int : Bool]
}
如果要在应用程序关闭时保存,则必须通过以下操作将复选标记数组保存在UserDefaults中:

在didSelectRow函数中,在完成所有操作后的底部添加以下内容:

if checkmarks[indexPath.row] != nil {
    cell.accessoryType = checkmarks[indexPath.row] ? .checkmark : .none
} else {
    checkmarks[indexPath.row] = false
    cell.accessoryType = .none
}
if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
    if cell.accessoryType == .checkmark{
        cell.accessoryType = .none
        checkmarks[indexPath.row] = false
    }
    else{
        cell.accessoryType = .checkmark
        checkmarks[indexPath.row] = true
    }
}
UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: checkmarks), forKey: "checkmarks")
UserDefaults.standard.synchronize()
if let checks = UserDefaults.standard.value(forKey: "checkmarks") as? NSData {
    checkmarks = NSKeyedUnarchiver.unarchiveObject(with: checks as Data) as! [Int : Bool]
}
然后,在viewDidLoad中,添加以下内容:

if checkmarks[indexPath.row] != nil {
    cell.accessoryType = checkmarks[indexPath.row] ? .checkmark : .none
} else {
    checkmarks[indexPath.row] = false
    cell.accessoryType = .none
}
if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
    if cell.accessoryType == .checkmark{
        cell.accessoryType = .none
        checkmarks[indexPath.row] = false
    }
    else{
        cell.accessoryType = .checkmark
        checkmarks[indexPath.row] = true
    }
}
UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: checkmarks), forKey: "checkmarks")
UserDefaults.standard.synchronize()
if let checks = UserDefaults.standard.value(forKey: "checkmarks") as? NSData {
    checkmarks = NSKeyedUnarchiver.unarchiveObject(with: checks as Data) as! [Int : Bool]
}
让我知道这个答案是否有用,如果你有任何问题

编辑:
所以我完全忘记的是,[Int:Bool]不是一本NSDictionary,它只是一本字典。UserDefaults不能存储Dictionary对象,只能存储NSDictionary对象,这就是为什么您必须将其更改为NSData,以便它能够保存[Int:Bool]。希望这次能正常工作:)

根据您的实现,UITableViewCell被重用,标识符为“List1”。因此,如果要重复使用单元格,则必须通过存储预定义任务的状态来不断更新正确的accessoryType。

由于单元格会被卸载并在以后重新使用,因此需要将复选标记的状态存储到其他位置。在本例中,在一个名为
preDefinedTaskCheckmarkState
的数组中。加载单元格时,还需要设置复选标记状态

var PreDefinedTasks = ["1", "2", "3", "4"]
var preDefinedTaskCheckmarkState = [Bool](repeating: false, count: 4)

// MARK: - Table view data source

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)

    if let cell = tableView.cellForRow(at: indexPath as IndexPath) {

        preDefinedTaskCheckmarkState[indexPath.row] = !(cell.accessoryType == .checkmark)

        cell.accessoryType = preDefinedTaskCheckmarkState[indexPath.row] ? .checkmark : .none
    }
}

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return PreDefinedTasks.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "List1", for: indexPath)

    cell.textLabel?.text = PreDefinedTasks[indexPath.row]
    cell.accessoryType = preDefinedTaskCheckmarkState[indexPath.row] ? .checkmark : .none

    return cell
}

您可以为选中和未选中的项目保留一个列表数组,并根据该数组设置cell.assessoryType。您能建议我如何操作吗?感谢您的回复:)因此,在didSelectRow委托方法中,您可以获得正确选择的行的indexpath。您可以将其存储在数组中,并在重新加载表时检查indexpath if matched在单元格上设置复选标记。谢谢,这确实帮助我更深入地理解了数据持久性。即使应用程序关闭,我如何更改此设置以保留数据?再次感谢你的回复:)编辑:我看不到你剩下的答案,对不起。我讨厌iMac:(我的措辞很奇怪,但我回答的最后一部分显示了当应用程序关闭时如何保存它。对此,我很抱歉。你的措辞很好,非常简洁。感谢你的帮助。它现在说“将bool类型的非可选值与nil类型的值进行比较总是返回true”,每当我加载表视图时就会崩溃:(让我看看这个,我会回来的,这是一个我没有考虑的方法。谢谢你的回复,很有用:)