简体   繁体   English

UserDefaults不将数据保留在TextView中

[英]UserDefaults not persisting data in TextView

Edit: I noticed I am using different keys (was playing with the code), but even if they are same, I get similar results. 编辑:我注意到我正在使用不同的键(正在玩代码),但是即使它们相同,我也会得到相似的结果。

I have looked all over StackOverflow but not found a solution for this. 我到处都在StackOverflow,但没有找到解决方案。 I have a textview on a second view in my storyboard, and I need it to persist the data without any button press. 我在情节提要中的第二个视图上有一个textview,我需要它来保持数据而无需按下任何按钮。 I should go to the view, see the text and when the app backgrounds (or view disappears), it should persist that data. 我应该去查看该视图,查看文本,并且当应用程序背景(或视图消失)时,它应该保留该数据。

I've got it working to the point the text appears on the second view (via a segue), but it doesn't update with new text which is appended via the loop and doesn't persist the data. 我已经设法使文本显示在第二个视图上(通过segue),但是它不会随着通过循环添加的新文本而更新,并且不会持久化数据。 Also, if I tap a "clear" button to clear the view, it clears the textview but as soon as I go back to the view, the data comes back. 另外,如果我点击“清除”按钮以清除视图,则会清除文本视图,但是一旦我返回视图,数据就会返回。

In essence it's stuck on saving just one line of my textview and nothing more. 本质上,它只保存了我的textview的一行,仅此而已。 Any help would be appriciated as I am very new to Xcode. 任何帮助都将适用,因为我是Xcode的新手。 (Latest Xcode with Swift 3). (最新的Xcode和Swift 3)。

import Foundation
import UIKit

class CalcViewController: UIViewController {
    var tape = Array<String>()

    @IBOutlet weak var calcTape: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        for eachNewLineInTape in tape {
            calcTape.text = calcTape.text + eachNewLineInTape + "\r\n"
        }

        let sel:Selector = #selector(self.appMovedToBackground)
        let notificationCentre = NotificationCenter.default
        notificationCentre.addObserver(self, selector: sel, name: NSNotification.Name.UIApplicationWillResignActive, object: nil)

        let defaults = UserDefaults.standard

        if let userDataNew:AnyObject = defaults.object(forKey: "userDataNew") as AnyObject?{
            calcTape.text = (userDataNew as! Array).first

            print("SAVED")
        }
        else {
            print("not saved")
        }
    }

    @IBAction func clearAll(_ sender: UIButton) {
        // if the tape is not empty...
        if (calcTape.text != ""){
            // empty it (set to empty string)
            calcTape.text = ""
            let bundleIdentifier = Bundle.main.bundleIdentifier
            UserDefaults.standard.removePersistentDomain(forName: bundleIdentifier!)
        } else {
            // otherwise, it was already empty, so display a message
            let alert = UIAlertController(title: "Alert", message: "Nothing to clear", preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }

    func appMovedToBackground(){
        print("App moved to background")
        let myText = calcTape.text
        UserDefaults.standard.set(myText, forKey: "savedStringKey")
        UserDefaults.standard.synchronize()
        print("saved")
    }
}

I assume that you tested and verified that appMovedToBackground is called. 我假设您已经测试并验证了appMovedToBackground的调用。

First, as it was mentioned in the comments, you need to use the same key. 首先,正如注释中提到的那样,您需要使用相同的密钥。

Then, in your saving code: 然后,在您的保存代码中:

let myText = calcTape.text
UserDefaults.standard.set(myText, forKey: "savedStringKey")

myText has String type, so it should store it as is. myText具有String类型,因此应按原样存储它。

But then in your loading code, you are doing something really strange. 但是然后在您的加载代码中,您所做的事情确实很奇怪。 This line should succeed and userDataNew will have your saved string. 该行应该成功,并且userDataNew将具有您保存的字符串。

if let userDataNew:AnyObject = defaults.object(forKey: "userDataNew") as AnyObject?{

But after that you are force casting it to Array . 但是之后,您必须将其强制转换为Array Your program must crash straight away: 您的程序必须立即崩溃:

calcTape.text = (userDataNew as! Array).first

The correct way for loading should be just: 正确的加载方式应该是:

calcTape.text = UserDefaults.standard.string(forKey: "savedStringKey")

Slightly off topic, but a few improvements in your code: Instead of this: 主题略有偏离,但您的代码有一些改进:代替此:

for eachNewLineInTape in tape {
   calcTape.text = calcTape.text + eachNewLineInTape + "\r\n"
}

you could write: 你可以这样写:

calcTape.text = tape.joined(separator: "\r\n")

Sorry for answering my own question (not sure how else to do it and make it clear), but this is how the code looks now: 很抱歉回答我自己的问题(不确定如何做并弄清楚),但这是现在代码的样子:

import Foundation
import UIKit

class ViewControllerTwo: UIViewController {

var tape = Array<String>()

@IBOutlet weak var calcTape: UITextView!



override func viewDidLoad() {
    super.viewDidLoad()

    calcTape.text = tape.joined(separator: "\r\n")

    let sel:Selector = #selector(self.appMovedToBackground)
    let notificationCentre = NotificationCenter.default
    notificationCentre.addObserver(self, selector: sel, name: NSNotification.Name.UIApplicationWillResignActive, object: nil)

    let defaults = UserDefaults.standard

    if let _:AnyObject = defaults.object(forKey: "savedStringKey") as AnyObject?{

        calcTape.text = UserDefaults.standard.string(forKey: "savedStringKey")

        print("SAVED")
    }
    else {
        print("not saved")
    }


}

@IBAction func clearAll(_ sender: UIButton) {

    // if the tape is not empty...
    if (calcTape.text != ""){

        // empty it (set to empty string)

        calcTape.text = ""
        let bundleIdentifier = Bundle.main.bundleIdentifier
        UserDefaults.standard.removePersistentDomain(forName: bundleIdentifier!)


    } else {
        // otherwise, it was already empty, so display a message
        let alert = UIAlertController(title: "Alert", message: "Nothing to clear", preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }
}


func appMovedToBackground(){
    print("App moved to background")
    let myText = calcTape.text
    UserDefaults.standard.set(myText, forKey: "savedStringKey")
    print("saved in bg")
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM