我正在处理基本应用的设置视图。基本,在用户的设置视图中只有一个开关。交换机设置随NSUserDefault一起保存。我使用委托将开关信号从设置视图发送到主视图。代表团工作正常。
用户界面是基本的。在主视图中,标签将显示为绿色(如果开关打开)和红色关闭(如果开关关闭。)右上方有一个设置按钮,它将segue(settingsSegue)设置为UITableViewController设置,UISwitch所在的地方。
问题是在应用加载后加载NSUserDefault。在viewDidLoad中,我检查是否为切换键保存了一个值。如果有,请加载它。如果没有,请将其设置为false(在故事板中,默认情况下将开关设置为false。)每次都会将“开关状态”加载为“关闭”。即使默认值为On。这不应该发生。
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()
}
}
}
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”的默认密钥。它是否正确?或者问题出在代码的其他地方?
答案 0 :(得分:1)
你可以依靠这样一个事实来整理一些事情:你需要的默认值是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()
}
}
}
<强> SettingsViewController.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")
}
}
答案 1 :(得分:0)
从用户默认值中检索bool值时,如果值不存在,boolForKey
将返回false。所以在这种情况下,不需要打开包装。来自文档:
如果布尔值与用户默认值中的defaultName相关联,则返回该值。否则,返回false。
如果值已设置(您确定),并且应用程序的行为无法正常工作,您的问题可能在其他地方。
我建议使用其他方法,宣布你的&#34; onFromMain&#34;作为可选的布尔值,然后在需要时解开它。
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永远不会被填充。
或者,您可以在视图加载方法上获取值,以便在加载应用时立即获取它。