永久数据和准备争夺

时间:2016-10-23 07:21:20

标签: arrays swift xcode segue

我正在尝试一起使用永久数据和准备癫痫。这是我到目前为止所做的:(查看控制器1)

override func viewDidAppear(_ animated: Bool) {

    let itemsObject = UserDefaults.standard.object(forKey: "items")


    if let tempItems = itemsObject as? [String] {

        items = tempItems

}
<视图控制器2中的

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "toSecondViewController" {

        let itemsObject = UserDefaults.standard.object(forKey: "items")

        var items:[String]

        if let tempItems = itemsObject as? [String] {

            items = tempItems

            items.append(textField.text!)

            print(items)

        } else {

            items = [textField.text!]

        }

        UserDefaults.standard.set(items, forKey: "items")


    }
}

我正在尝试将一个项目添加到VC2上的数组中。然后我想将数组传输到VC1,同时也永久存储它。然后每次我关闭并重新加载应用程序时,我都可以打印数组。错误消息指出“使用未解析的标识符项”。我正在使用Xcode 8.0和Swift 3.0。

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:1)

你忘记在viewDidAppear中写“let”或“var”。试试这个:

override func viewDidAppear(_ animated: Bool) {

    let itemsObject = UserDefaults.standard.object(forKey: "items")


    if let tempItems = itemsObject as? [String] {

        let items = tempItems

    }
}

如果要在if语句之后使用项目,则必须在if语句之前声明变量:

override func viewDidAppear(_ animated: Bool) {

    let itemsObject = UserDefaults.standard.object(forKey: "items")

    var items: [String]
    if let tempItems = itemsObject as? [String] {

        items = tempItems
    }
}

答案 1 :(得分:1)

好的,因为您说要在应用程序启动时保留数据,您将需要用户默认值来存储您的项目。正如Dan已经建议你基本上做得对。您只想设置之前未声明的变量。但我会在下面的代码中向您展示。我还将附加第二种方法,在执行segue时将项目传递给下一个视图控制器。

第一个例子:想象一下,我们在你的例子中有两个视图控制器。第一个视图控制器包含一个UITextField来执行用户文本输入。每当我们在故事板segue的帮助下从第一个视图控制器切换到第二个视图控制器时(例如,当按下按钮时),我们从用户默认值中获取先前segue中的现有文本并添加当前用户输入然后再保留到用户默认值。这发生在第一个视图控制器中:

class ViewController: UIViewController {

@IBOutlet weak var textField: UITextField!

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)

    if segue.identifier == "toSecondViewController" {
        let itemsFromDefaults = UserDefaults.standard.object(forKey: "items")

        var items: [String]

        if let tempItems = itemsFromDefaults as? [String]
        {
            items = tempItems
            items.append(textField.text!)
        }
        else
        {
            items = [textField.text!]
        }

        print(items)

        UserDefaults.standard.set(items, forKey: "items")
    }
}
}

这个第一个视图控制器看起来与你的代码非常相似,但我想添加它以保持完整性。

然后在第二个视图控制器中,我们只从用户默认值中获取项目,并将其直接存储在此视图控制器的实例变量中。借助于此,我们可以在视图控制器中的其他方法中执行我们想要的操作,并进一步处理项目。正如我所说,你所缺少的是用于存储项目的实例变量声明。

class ViewController2: UIViewController {

private var items: [String]? // This is only accessible privately

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    self.items = UserDefaults.standard.object(forKey: "items") as? [String]
}

}

第二个示例:您还可以在ViewController2中声明一个内部/公共变量,以便您可以在执行segue中直接从第一个视图控制器设置它。您不需要从ViewController2中的用户默认值中获取项目。为此,您可以访问segue的目标视图控制器,然后将其转换为ViewController2并直接设置它的项目。

class ViewController: UIViewController {

@IBOutlet weak var textField: UITextField!

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)

    if segue.identifier == "toSecondViewController" {

        let itemsFromDefaults = UserDefaults.standard.object(forKey: "items")

        var items: [String]

        // [...] Do the stuff to get the items and add current input like before [...]

        let destinationViewController = segue.destination as! ViewController2

        destinationViewController.items = items
    }
}
}

class ViewController2: UIViewController {

var items: [String]? // This is accessible from outside now

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    print(items) // We can now print this because it is set in prepareForSegue
}

}

我真的希望我可以帮助你并解释它是可以理解的。如果您有任何问题,请随时发表评论。