【问题标题】:User defaults Only Working On Restart用户默认值仅在重新启动时工作
【发布时间】:2017-08-16 13:40:19
【问题描述】:

我正在尝试在我的应用程序中实现明暗模式。在settingsViewController 我有这些代码行:

//Sets user default for colour
let lightMode = UserDefaults.standard.bool(forKey: "lightMode")

//UISegment control for user to pick colour
@IBOutlet var colourSegment: UISegmentedControl!

//Updates lightMode based on user selection
@IBAction func didChangeColours(_ sender: Any) {

    if colourSegment.selectedSegmentIndex == 0 {
        UserDefaults.standard.set(true, forKey: "lightMode")
    } else if colourSegment.selectedSegmentIndex == 1 {
        UserDefaults.standard.set(false, forKey: "lightMode")
    }

}

在我的entryViewController,在我的viewDidLoad,我有:

let lightMode = UserDefaults.standard.bool(forKey: "lightMode")

if lightMode == false {
    Colours.darkMode()
}

customisations()

我遇到的问题是,由于某种原因,我的应用程序只是在重新启动后才更改它的配色方案。也就是说,如果用户选择colourSegmentdarkIndex,应用程序只有在我重新启动后才会更新颜色。我想知道这个问题的解决方案是什么。

【问题讨论】:

  • 如您所说,您只需读取并设置 viewDidLoad 中的颜色。您需要将相同的逻辑放入didChangeColor: 函数中。
  • 你能扩展一下吗?
  • 当您单击分段控件时,您只需将值存储在 UserDefaults 中,但您不会在那里更新 UI。您只能在 viewDidLoad 中更新它。您需要做的是将相同的逻辑(设置 ui 的颜色)放入 didChangeColours: 方法中。

标签: ios swift nsuserdefaults


【解决方案1】:

问题出在一行——

//Sets user default for colour
let lightMode = UserDefaults.standard.bool(forKey: "lightMode")

此行不是用于设置 Userdefaults,而是用于获取 UserDefaults。由于您在设置默认值之前使用它,因此它不能反映正确的分段选择。因此,您的设置部分是正确的,您应该仅在设置后获取该值。

同样在您的 entryViewController 中,而不是从 settingsVC 中使用它,请执行以下操作 -

//get from UserDefaults
let lightMode = UserDefaults.standard.bool(forKey: "lightMode")

//Compare the previous fetched value
if lightMode == false {
    Colours.darkMode()
}

//This function sets the colour for the elements
colours()

【讨论】:

  • 我该如何改变它?
  • 您在分段控件的 didChangeColors 中的更改代码是正确的,这将保存用户默认值
  • 您介意解释一下“此行不是用于设置 USerdefaults 而是获取 userdefaults 的意思。由于您在设置 ti 之前使用它,因此它不能反映正确的分段选择。 "
  • 所以这行代码是使用键“lightMode”从用户默认值中获取值。所以当你第一次打开设置时会发生什么,它没有任何价值,所以总是假的。我假设这会保存在您的 settingsVC.lightMode 中。现在,当用户设置它时,您将其保存在 userdefaults 中,这很好。现在在您的 entryViewController 中,您可以从 userdefaults 中获取它,这样您将获得正确的值。但是如果你从 settingsVC.lightMode 中得到它,因为它是一个旧值,你不能在下一个 VC 中得到它
  • 所以我尝试植入你的代码,它仍然没有工作。您还有什么建议吗?
【解决方案2】:

因为您在初始化期间只分配了 1 次 lightMode 值,所以您不会反映对变量的更改,因此它始终是该值

要始终获得最新的值,请使用:

let lightMode: Bool {
   get {
       return UserDefaults.standard.bool(forKey: "lightMode")
   }
}

另外,你应该在更改值后立即调用颜色更改

【讨论】:

    【解决方案3】:

    我假设您从您的settingsViewController 返回到您的entryViewController;由于您要返回到现有的视图控制器实例,所以在您返回时不会执行viewDidLoad 中的代码。

    将代码移至viewWillAppear;这样,即使您返回现有实例,您的代码也会在视图控制器出现之前执行:

    func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let lightMode = UserDefaults.standard.bool(forKey: "lightMode")
    
        if lightMode == false {
            Colours.darkMode()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-12
      • 1970-01-01
      • 2016-08-14
      • 2020-01-21
      • 1970-01-01
      • 2013-10-12
      • 1970-01-01
      • 2021-03-05
      相关资源
      最近更新 更多