如何再次保存和加载列表?

How to save and load a list again?

我正在尝试使用 table 视图编写一个简单的应用程序来展示一些可以做的事情。 (这里就叫"Grails"/我要买的东西)

关于 table 视图、输入等等我都做了,我唯一需要做的就是再次保存和加载所有信息。但是我不知道怎么办。

这是我在第一个视图控制器上的代码:

import UIKit

var list = ["Nike Air Jordan 1 x Off White", "Balenciaga Speed Trainers", "Gucci Snake Sneakers", "Goyard Card Holder"]

class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var myTableView: UITableView!

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

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
        cell.textLabel?.text = list[indexPath.row]

        return cell
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == UITableViewCellEditingStyle.delete {
            list.remove(at: indexPath.row)
            myTableView.reloadData()
        }
    }

    override func viewDidAppear(_ animated: Bool) {
        myTableView.reloadData()
    }
}

第二个视图控制器如下所示:

import UIKit

class SecondViewController: UIViewController {

    @IBOutlet weak var input: UITextField!

    @IBAction func addItem(_ sender: Any) {
        if (input.text != "") {
            list.append(input.text!)
            input.text = ""
        }
    }
}

编辑:

现在代码看起来像这样,但是我无法从第二个视图控制器上的按钮向列表中添加任何新项目?

导入 UIKit

var list = ["Nike Air Jordan 1 x Off White", "Balenciaga Speed Trainers", "Gucci Snake Sneakers", "Goyard Card Holder"]

class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var myTableView: UITableView!


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

func updateData() {
    UserDefaults.standard.set(list, forKey: "list")
    myTableView.reloadData()
}

//LOADING THE DATA AGAIN
override func viewDidLoad() {
    if let storedList = UserDefaults.standard.value(forKey: "list")
    {
        list = storedList as! [String]
    }
    else
    {
        print("No list previously stored")
    }
}


public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
    cell.textLabel?.text = list[indexPath.row]

    return cell
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
{
    if tableView.cellForRow(at: indexPath)?.accessoryType == UITableViewCellAccessoryType.checkmark
    {
        tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCellAccessoryType.none
    }
    else
    {
        tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCellAccessoryType.checkmark
    }
}



func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool
{
    return true
}


func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
{
    let item = list[sourceIndexPath.row]
    list.remove(at: sourceIndexPath.row)
    list.insert(item, at: destinationIndexPath.row)
}

@IBAction func edit(_ sender: Any)
{
    myTableView.isEditing = !myTableView.isEditing

    switch myTableView.isEditing {
    case true:
        editButtonItem.title = "Done"
    case false:
        editButtonItem.title = "Edit"
    }
}


func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
    if editingStyle == UITableViewCellEditingStyle.delete
    {
        list.remove(at: indexPath.row)
        updateData()
    }
}

override func viewDidAppear(_ animated: Bool) {
    updateData()
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

好的,如上面的评论所述,在这种情况下您很可能会使用 UserDefaults.standard,因为您要处理的数据量很小。如果您希望每次更新数据时都更新它(add/remove 一个新项目),那么您应该进行一些代码重构以将 saving 部分与 myTableView.reloadData()。操作方法如下:

func updateData() {
    UserDefaults.standard.set(list, forKey: "list")
    myTableView.reloadData()
}

然后你会在你调用 myTableView.reloadData() 的任何地方调用 updateData() (只是为了让我自己清楚:替换它,因为该方法已经包含 reload 部分)。这就是节省部分。现在你必须处理 loading,通常你会在 AppDelegate class 中的 application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 方法中这样做,但为了简单起见,让我们只教你如何在里面做你已经在 FirstViewController class:

中缺少 viewDidLoad() 方法
override func viewDidLoad() {
    if let storedList = UserDefaults.standard.value(forKey: "list") {
        list = storedList as! [String] 
    } else {
        print("No list previously stored")
    }
}

如果存储了任何先前的 list,则替换该值。否则它会打印消息作为确认(如果需要,您可以在将来删除它,以便保留控制台日志以获取有用的东西)。

我必须说的最后一件事是我做了 强制施法 因为我知道 storedList 事实上它是 String数组,但你应该非常小心地使用 as!。始终执行安全投射,因为如果失败,您的应用程序将崩溃。