UserDefaults不在TextView

时间:2017-02-22 22:53:44

标签: ios swift nsuserdefaults

编辑:我注意到我正在使用不同的密钥(正在使用代码),但即使它们相同,我也会得到类似的结果。

我已经遍布StackOverflow,但没有找到解决方案。我在故事板中的第二个视图上有一个textview,我需要它来保持数据而不需要按任何按钮。我应该去视图,看到文本,当应用程序背景(或视图消失)时,它应该保留该数据。

我已经让它工作到文本出现在第二个视图上(通过segue),但它没有使用通过循环附加的新文本进行更新,并且没有坚持数据。此外,如果我点击"清除"按钮清除视图,它清除文本视图,但一旦我返回到视图,数据就会恢复。

从本质上说,它只是在保存我的textview的一行而已。任何帮助都会受到影响,因为我对Xcode很新。 (最新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")
    }
}

2 个答案:

答案 0 :(得分:0)

我假设您测试并验证了appMovedToBackground被调用。

首先,正如评论中提到的那样,您需要使用相同的密钥。

然后,在您的保存代码中:

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

myText具有String类型,因此它应该按原样存储。

但是在你的加载代码中,你正在做一些非常奇怪的事情。此行应该成功,userDataNew将保存您的字符串。

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

但在此之后你强行将它投射到Array。你的程序必须立即崩溃:

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

加载的正确方法应该是:

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

稍微偏离主题,但代码中有一些改进: 而不是:

for eachNewLineInTape in tape {
   calcTape.text = calcTape.text + eachNewLineInTape + "\r\n"
}
你可以写:

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

答案 1 :(得分:0)

很抱歉回答我自己的问题(不知道该怎么做并说清楚),但这就是代码现在的样子:

#include<iostream>
using namespace std;
void balloon()
{ int num, N[10], x, y, z,temp;
clrscr();
cout<<"How many number would you like to sort? ";
cin>>num;
cout<<"Input the "<<num<<" numbers:"<<endl;
for(x=0;x<num;x++)
cin>>N[x];
for(x=0;x<num;x++)
{
for(y=0;y<num-x;y++)
{ if(N[x] > N[x+y])
{ temp=N[x];
N[x] =N[x+y];
N[x+y]=temp;
}
}
cout<<"pass "<<x+1<<"] ";
for(z=0;z<num;z++)
{
cout<<setw(5)<<N[z];
}
cout<<endl;
}
}