在加载时从 NSUserDefault 加载开关状态
Loading a switch state from NSUserDefault on load
我正在为一个基本应用开发设置视图。基本,在用户的设置视图中只有一个开关。开关设置保存在 NSUserDefault 中。我使用委托将开关信号从设置视图发送到主视图。代表团工作正常。
UI 是基本的。在主视图上,标签将以绿色显示“打开”(如果开关打开)和“关闭”红色(如果开关关闭)。右上角有一个设置按钮,可以将 (settingsSegue) 转到设置 UITableViewController,UI开关所在的位置。
问题是在应用加载后加载 NSUserDefault。在 viewDidLoad 中,我检查是否为切换键保存了一个值。如果有,请加载它。如果不是,将其设置为 false(在故事板中,开关默认设置为 false。)开关状态每次都加载为关闭。即使默认值为开。这不应该发生。
ViewController.swift:
import UIKit
var nsDefaults = NSUserDefaults.standardUserDefaults()
class ViewController: UIViewController, SettingsViewControllerDelegate {
var onFromMain = Bool()
@IBOutlet weak var switchStateLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
if let mySavedKey = nsDefaults.objectForKey("savedSwitchSettingDefault") {
// A value exists. Load it up.
nsDefaults.objectForKey("savedSwitchSettingDefault")
print("The switch is set! \(mySavedKey)")
checkSwitchState()
}
else {
// Nothing stored in NSUserDefaults yet. Set switch to False.
nsDefaults.setBool(false, forKey: "savedSwitchSettingDefault")
checkSwitchState()
}
}
func myVCDidFinish(controller: SettingsViewController, switchState: Bool) {
onFromMain = switchState.boolValue
checkSwitchState()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "settingsSegue" {
let nav = segue.destinationViewController as! UINavigationController
let secondVC = nav.topViewController as! SettingsViewController
secondVC.delegate = self
}
}
func checkSwitchState() {
if onFromMain {
switchStateLabel.text = "On"
switchStateLabel.textColor = UIColor.greenColor()
}
else {
switchStateLabel.text = "Off"
switchStateLabel.textColor = UIColor.redColor()
}
}
}
设置ViewController.swift:
import UIKit
protocol SettingsViewControllerDelegate {
func myVCDidFinish(controller: SettingsViewController, switchState: Bool)
}
class SettingsViewController: UITableViewController {
var delegate: SettingsViewControllerDelegate? = nil
@IBOutlet weak var switchOutlet: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
switchOutlet.on = nsDefaults.boolForKey("savedSwitchSettingDefault")
}
@IBAction func closeSettingsPageBarButtonItemPressed(sender: UIBarButtonItem) {
if (delegate != nil) {
delegate!.myVCDidFinish(self, switchState: switchOutlet.on)
self.dismissViewControllerAnimated(true, completion: nil)
}
}
@IBAction func switchPressed(sender: UISwitch) {
// Tap the switch to change the setting.
nsDefaults.setBool(switchOutlet.on, forKey: "savedSwitchSettingDefault")
}
}
我认为我的问题在于加载 "savedSwitchSettingDefault" 的默认密钥。这个对吗?还是问题出在代码的其他地方?
你可以根据你想要的默认值是 false
并且当密钥不存在时 boolForKey
给你 false
这样的事实来整理一下.
此外,通过访问 viewWillAppear
中的设置,您可以避免对委托回调的需要。
ViewController.swift
import UIKit
class ViewController: UIViewController {
let nsDefaults = NSUserDefaults.standardUserDefaults()
var onFromMain = false
@IBOutlet weak var switchStateLabel: UILabel!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.onFromMain = self.nsDefaults.boolForKey("savedSwitchSettingDefault")
self.checkSwitchState()
}
func checkSwitchState() {
if self.onFromMain {
switchStateLabel.text = "On"
switchStateLabel.textColor = UIColor.greenColor()
}
else {
switchStateLabel.text = "Off"
switchStateLabel.textColor = UIColor.redColor()
}
}
}
设置ViewController.swift:
import UIKit
class SettingsViewController: UITableViewController {
let nsDefaults = NSUserDefaults.standardUserDefaults()
@IBOutlet weak var switchOutlet: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.switchOutlet.on = self.nsDefaults.boolForKey("savedSwitchSettingDefault")
}
@IBAction func closeSettingsPageBarButtonItemPressed(sender: UIBarButtonItem) {
self.dismissViewControllerAnimated(true, completion: nil)
}
@IBAction func switchPressed(sender: UISwitch) {
// Tap the switch to change the setting.
self.nsDefaults.setBool(self.switchOutlet.on, forKey: "savedSwitchSettingDefault")
}
}
从用户默认值中检索 bool 值时,如果该值不存在,boolForKey
将 return 为假。所以在这种情况下不需要展开。来自文档:
If a boolean value is associated with defaultName in the user defaults, that value is returned. Otherwise, false is returned.
如果正在设置值(您确定),并且应用程序的行为无法正常工作,则您的问题可能出在其他地方。
我建议使用另一种方法,将您的 "onFromMain" 声明为可选的布尔值,然后在需要时将其解包。
var onFromMain: Bool?
...
func checkSwitchState() {
//- This will unwrap your optional or set false if its nil
let switchSate = onFromMain ?? false
//- Then you can set the values based on the value (or the default false)
switchStateLabel.text = switchState ? "On" : "Off"
switchStateLabel.textColor = switchState ? UIColor.greenColor() : UIColor.redColor()
}
然后在调试器上附加一个断点,看看该值是否正在解包或者它是否默认为 false。
此外,您仅在调用 segue 时才设置委托,这取决于具体情况,如果我理解正确的话,在您实际导航到设置视图之前,您可能不会获得该值。因此,当打开应用程序(不导航到设置视图)时,onFromMain 将永远不会被填充。
或者,您可以在加载应用程序时直接获取视图加载方法中的值。
我正在为一个基本应用开发设置视图。基本,在用户的设置视图中只有一个开关。开关设置保存在 NSUserDefault 中。我使用委托将开关信号从设置视图发送到主视图。代表团工作正常。
UI 是基本的。在主视图上,标签将以绿色显示“打开”(如果开关打开)和“关闭”红色(如果开关关闭)。右上角有一个设置按钮,可以将 (settingsSegue) 转到设置 UITableViewController,UI开关所在的位置。
问题是在应用加载后加载 NSUserDefault。在 viewDidLoad 中,我检查是否为切换键保存了一个值。如果有,请加载它。如果不是,将其设置为 false(在故事板中,开关默认设置为 false。)开关状态每次都加载为关闭。即使默认值为开。这不应该发生。
ViewController.swift:
import UIKit
var nsDefaults = NSUserDefaults.standardUserDefaults()
class ViewController: UIViewController, SettingsViewControllerDelegate {
var onFromMain = Bool()
@IBOutlet weak var switchStateLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
if let mySavedKey = nsDefaults.objectForKey("savedSwitchSettingDefault") {
// A value exists. Load it up.
nsDefaults.objectForKey("savedSwitchSettingDefault")
print("The switch is set! \(mySavedKey)")
checkSwitchState()
}
else {
// Nothing stored in NSUserDefaults yet. Set switch to False.
nsDefaults.setBool(false, forKey: "savedSwitchSettingDefault")
checkSwitchState()
}
}
func myVCDidFinish(controller: SettingsViewController, switchState: Bool) {
onFromMain = switchState.boolValue
checkSwitchState()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "settingsSegue" {
let nav = segue.destinationViewController as! UINavigationController
let secondVC = nav.topViewController as! SettingsViewController
secondVC.delegate = self
}
}
func checkSwitchState() {
if onFromMain {
switchStateLabel.text = "On"
switchStateLabel.textColor = UIColor.greenColor()
}
else {
switchStateLabel.text = "Off"
switchStateLabel.textColor = UIColor.redColor()
}
}
}
设置ViewController.swift:
import UIKit
protocol SettingsViewControllerDelegate {
func myVCDidFinish(controller: SettingsViewController, switchState: Bool)
}
class SettingsViewController: UITableViewController {
var delegate: SettingsViewControllerDelegate? = nil
@IBOutlet weak var switchOutlet: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
switchOutlet.on = nsDefaults.boolForKey("savedSwitchSettingDefault")
}
@IBAction func closeSettingsPageBarButtonItemPressed(sender: UIBarButtonItem) {
if (delegate != nil) {
delegate!.myVCDidFinish(self, switchState: switchOutlet.on)
self.dismissViewControllerAnimated(true, completion: nil)
}
}
@IBAction func switchPressed(sender: UISwitch) {
// Tap the switch to change the setting.
nsDefaults.setBool(switchOutlet.on, forKey: "savedSwitchSettingDefault")
}
}
我认为我的问题在于加载 "savedSwitchSettingDefault" 的默认密钥。这个对吗?还是问题出在代码的其他地方?
你可以根据你想要的默认值是 false
并且当密钥不存在时 boolForKey
给你 false
这样的事实来整理一下.
此外,通过访问 viewWillAppear
中的设置,您可以避免对委托回调的需要。
ViewController.swift
import UIKit
class ViewController: UIViewController {
let nsDefaults = NSUserDefaults.standardUserDefaults()
var onFromMain = false
@IBOutlet weak var switchStateLabel: UILabel!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.onFromMain = self.nsDefaults.boolForKey("savedSwitchSettingDefault")
self.checkSwitchState()
}
func checkSwitchState() {
if self.onFromMain {
switchStateLabel.text = "On"
switchStateLabel.textColor = UIColor.greenColor()
}
else {
switchStateLabel.text = "Off"
switchStateLabel.textColor = UIColor.redColor()
}
}
}
设置ViewController.swift:
import UIKit
class SettingsViewController: UITableViewController {
let nsDefaults = NSUserDefaults.standardUserDefaults()
@IBOutlet weak var switchOutlet: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.switchOutlet.on = self.nsDefaults.boolForKey("savedSwitchSettingDefault")
}
@IBAction func closeSettingsPageBarButtonItemPressed(sender: UIBarButtonItem) {
self.dismissViewControllerAnimated(true, completion: nil)
}
@IBAction func switchPressed(sender: UISwitch) {
// Tap the switch to change the setting.
self.nsDefaults.setBool(self.switchOutlet.on, forKey: "savedSwitchSettingDefault")
}
}
从用户默认值中检索 bool 值时,如果该值不存在,boolForKey
将 return 为假。所以在这种情况下不需要展开。来自文档:
If a boolean value is associated with defaultName in the user defaults, that value is returned. Otherwise, false is returned.
如果正在设置值(您确定),并且应用程序的行为无法正常工作,则您的问题可能出在其他地方。
我建议使用另一种方法,将您的 "onFromMain" 声明为可选的布尔值,然后在需要时将其解包。
var onFromMain: Bool?
...
func checkSwitchState() {
//- This will unwrap your optional or set false if its nil
let switchSate = onFromMain ?? false
//- Then you can set the values based on the value (or the default false)
switchStateLabel.text = switchState ? "On" : "Off"
switchStateLabel.textColor = switchState ? UIColor.greenColor() : UIColor.redColor()
}
然后在调试器上附加一个断点,看看该值是否正在解包或者它是否默认为 false。
此外,您仅在调用 segue 时才设置委托,这取决于具体情况,如果我理解正确的话,在您实际导航到设置视图之前,您可能不会获得该值。因此,当打开应用程序(不导航到设置视图)时,onFromMain 将永远不会被填充。
或者,您可以在加载应用程序时直接获取视图加载方法中的值。