Userdefaults Tableview地标Swift 3

时间:2017-01-25 02:28:52

标签: swift swift3 tableview nsuserdefaults

我正在使用 uitableview 。当我选择一个单元格时,我正在尝试保存地标。从下面的代码我添加了一个tableview,当我选择一个单元格时,将显示地标。但是我在保存它时遇到了麻烦,因为当我去另一个视图控制器并返回时它没有显示。我研究过并发现我需要使用 UserDefaults ,但我不知道如何使用它。有人能指出我怎样才能实现这一目标。感谢

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

    let contactsCell = app.helper.contacts[indexPath.row]
    cell!.textLabel?.text = contactsCell

    return cell!
}


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let contactToCall = app.helper.contacts[indexPath.row]
    app.helper.contactSelected = contactToCall

    if let cell = tableView.cellForRow(at: indexPath) {
        if cell.isSelected {
            cell.accessoryType = .checkmark


        }
    }

}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {

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

1 个答案:

答案 0 :(得分:0)

除非你想在应用程序关闭并重新启动后保持状态,否则你不需要UserDefaults,一旦你开始存储用户默认值,你可能想要存储更多 - 所以创建默认值是有意义的用于存储所选索引的数据类以及您可能需要的任何其他“东西”。

在此示例中,我将在viewDidLoad上加载默认值,并在每次选择/取消选择时存储默认值。如果您存储了其他值,则应该有其他存储调用。

创建一个用于存储数据的类

class MyDefaultsData : NSObject, NSCoding
{
    var selectedIndexPath : IndexPath?
    var otherStuff : String?

    override init()
    {
        // you can set up default values here if you need them
        selectedIndexPath = nil
        otherStuff = nil
    }

    // archiving code
    func encode(with aCoder: NSCoder)
    {
        // you can't store IndexPath directly, so split it into row and section
        if selectedIndexPath == nil
        {
            // set invalid values which we can identify later
            aCoder.encode(-1, forKey: "indexSection")
            aCoder.encode(-1, forKey: "indexRow")
        }
        else
        {
            aCoder.encode(selectedIndexPath!.section, forKey: "indexSection")
            aCoder.encode(selectedIndexPath!.row, forKey: "indexRow")
        }
        aCoder.encode(otherStuff, forKey: "otherStuff")
    }

    required init(coder aDecoder: NSCoder)
    {
        let indexSection = aDecoder.decodeInteger(forKey: "indexSection")
        let indexRow = aDecoder.decodeInteger(forKey: "indexRow")
        if indexSection != -1 && indexRow != -1  // if no row is selected, these values will both be -1
        {
            selectedIndexPath   = IndexPath(row: indexRow, section: indexSection)
        }
        else
        {
            selectedIndexPath = nil
        }

        self.otherStuff     = aDecoder.decodeObject(forKey: "otherStuff") as? String
    }

}

在ViewController中定义默认数据的变量

var defaultData         = MyDefaultsData()

viewDidLoad

中加载数据
override func viewDidLoad()
{
    loadDefaults()
}

func loadDefaults()
{
    var dataDefaults : MyDefaultsData?
    if let data = UserDefaults.standard.object(forKey: "NSDefaultsTest") as? Data
    {
        dataDefaults =  NSKeyedUnarchiver.unarchiveObject(with: data) as? MyDefaultsData

        self.defaultData.otherStuff = dataDefaults?.otherStuff ?? "No value found"

        self.defaultData.selectedIndexPath = dataDefaults?.selectedIndexPath
    }
}

然后您在cellForRowAt

中使用该默认数据
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")

    let contactsCell = app.helper.contacts[indexPath.row]
    cell!.textLabel?.text = contactsCell

    // set or clear the checkmark
    if selectedIndexPath == indexPath
    {
        cell.accessoryType = .checkmark
    }
    else
    {
        cell.accessoryType = .none
    }
    return cell!
}

当您更改所选行时,您需要重新加载上一个选定行(如果有)和当前选定的行,以获得勾选标记

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
    let previousIndexPath = defaultData.selectedIndexPath
    if previousIndexPath != indexPath
    {
        defaultData.selectedIndexPath = indexPath
    }
    else
    {
        defaultData.selectedIndexPath = nil
    }
    storeDefaults()


    if previousIndexPath != nil
    {
        tableView.reloadRows(at: [previousIndexPath!], with: .automatic)
    }
    if defaultData.selectedIndexPath != nil
    {
        tableView.reloadRows(at: [defaultData.selectedIndexPath!], with: .automatic)
    }
}