使用 UserDefaults 相互替换的值

Posted

技术标签:

【中文标题】使用 UserDefaults 相互替换的值【英文标题】:Values replacing each other using UserDefaults 【发布时间】:2017-09-24 09:48:44 【问题描述】:

我有一个应用程序,我可以在其中给自己计时,看看我需要多长时间才能完成一堆问题。我将时间转移到另一个 VC 并显示在标签中。我通过按下按钮来存储它,但是当我有一个新变量(时间)时,它会替换它。如何存储一个值数组并显示在标签中?

保存值的按钮:

@IBAction func saveScore(_ sender: Any) 
    scoreLabel.text = label.text
    UserDefaults.standard.set(scoreLabel.text, forKey: "score")

永久保存数据的代码:

override func viewDidAppear(_ animated: Bool) 
    if let x = UserDefaults.standard.object(forKey: "score") as? String 
        scoreLabel.text = x
    

我的 scoreLabel 显示我所有的分数,标签显示你刚刚得到的时间。

【问题讨论】:

【参考方案1】:

UserDefaults 上使用以下扩展来存储时间数组:

extension UserDefaults 
    var times: [String] 
        get 
            if let times = UserDefaults.standard.object(forKey: "times") as? [String] 
                return times
             else 
                return []
            
        
        set 
            UserDefaults.standard.set(newValue, forKey: "times")
        
    

虽然您不需要扩展 UserDefaults,但使用扩展可以简化对持久值的处理,并且使代码更简洁。

然后在显示数据的地方,使用以下行访问数组:

let arrayOfTimes = UserDefaults.standard.times
scoreLabel.text = "\(arrayOfTimes)" // or any other formatting you'd like

而不是设置时间来保持新分数,只需将新分数添加到数组中,例如:

// This will not only add the scoreLabel.text to the array, but also persists it
UserDefaults.standard.times.append(scoreLabel.text)

【讨论】:

感谢米兰的帮助,非常感谢!但是,当我完成游戏时,它会显示“标签”而不是标签所说的内容,例如 23.5 秒,除此之外其他一切都很好 这不是 UserDefaults 的问题。很可能是您设置标签文本时(以及将数据保存到 UserDefaults 时)的问题。检查您的代码并尝试将数据尽快保存到 UserDefaults 中,并在出现标签时尽快从 UserDefaults 刷新标签。最后,您甚至不必在viewControllers之间传递它,只需在到达末尾时添加值,并在带有标签的viewController中使用来自UserDefaults的数据 好的,谢谢,我会告诉你我的进展,谢谢! 我需要将 UserDefaults.standard.times.append(down.text) 添加到 saveScore 按钮。以及删除 viewDidAppear 中的所有内容并添加 if let x = UserDefaults.standard.object(forKey: "times") as?字符串 resultLabel.text = x 【参考方案2】:

在 Swift 4 中,

将数组保存到用户默认值,您可以:

 let defaults = UserDefaults.standard

 let array = [25, 50]

 defaults.set(array, forKey: "Scores")

并且从用户默认值访问数组:

 let defaults = UserDefaults.standard

 let retrievedArray = defaults.array(forKey: "Scores") as? [Int] ?? []

如果你要在标签中显示你的数组的分数,你会这样做:

 scoreLabel.text = String(describing: retrievedArray[0])

如果您在评分系统中使用整数,我建议您 在用户默认值中将您的分数存储为Int

如果您更喜欢使用Strings,请注意,您可以直接使用用户默认值的stringArray(forKey:) 方法,而不是array(forKey:) 方法,因此,在这种情况下,您不需要键入投射你的数组:

let someStringArray = defaults.stringArray(forKey: "ArrayOfStrings")

注意:为了回答您的问题,我认为您使用的是 Int 分数,但您可以随意使用任何您喜欢的分数。

如果您想将数组存储到用户默认值中的相同键每次获得新分数时,您可以像这样轻松地做到这一点:

let defaults = UserDefaults.standard

// Your new score:

let newScore = 75

// Get your current scores list from User Defaults:

var currentArray = defaults.array(forKey: "Scores") as? [Int] ?? []

// Append your new score to the current array:              

let updatedArray = currentArray.append(newScore)

// And save your updated array to User Defaults:

defaults.set(updatedArray, forKey: "Scores")

// In this example, your User Defaults now contains the updated array [25, 50, 75]

就是这样:)。

请注意,不需要为此使用扩展程序。

更新:另外,如果您想在 viewDidAppear 方法中添加一些内容,请不要忘记添加 super.viewDidAppear(animated)viewDidLoad 等也是如此。

documentation 声明:

您可以重写此方法以执行相关的其他任务 与呈现视图。如果重写此方法,则必须调用 在你的实现中的某个时刻超级。

所以你会:

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

    if let retrievedArray = defaults.array(forKey: "Scores") as? [Int] 

        print(retrievedArray)

        // You can access your scores array safely here
    

【讨论】:

我不确定我应该把这段代码放在哪里。我的保存分数按钮和 viewDidAppear 中的 userDefaults 代码应该有哪些代码。我已将代码放在我认为它所在的位置,但目前无法正常工作。顺便说一句,我使用的是字符串,但我应该使用整数。到目前为止谢谢! 如果你的分数在你的应用中代表一个整数,那么你最好将它保存为一个 Int 确实,它会更有意义。当然,您仍然可以使用 String(describing:) 在标签中显示您的分数,就像我在答案中显示的那样。 好吧,您应该将此代码放在您的@IBAction(保存分数)中,因为您希望在用户点击保存分数按钮时将新分数保存到用户默认值。 :) 不客气!如果您有任何其他问题,请告诉我:)。 感谢亚历克斯的所有帮助!

以上是关于使用 UserDefaults 相互替换的值的主要内容,如果未能解决你的问题,请参考以下文章

当我尝试使用 UserDefaults(watchOS)从共享组中读取时,为啥我的值为零

如何在 UserDefaults 中重置“AppleLanguages”键的值

UserDefaults 在同一个应用程序组中具有不同的值

我必须使用标准共享 UserDefaults 对象吗?

UserDefaults不保存值iphone

sed在替换的时候,使用变量中的值?如何在sed实现变量的替换?获取到变量中的值?