在加载时从NSUserDefault加载交换机状态

时间:2016-05-31 22:07:39

标签: ios swift settings nsuserdefaults

我正在处理基本应用的设置视图。基本,在用户的设置视图中只有一个开关。交换机设置随NSUserDefault一起保存。我使用委托将开关信号从设置视图发送到主视图。代表团工作正常。

用户界面是基本的。在主视图中,标签将显示为绿色(如果开关打开)和红色关闭(如果开关关闭。)右上方有一个设置按钮,它将segue(settingsSegue)设置为UITableViewController设置,UISwitch所在的地方。

问题是在应用加载后加载NSUserDefault。在viewDidLoad中,我检查是否为切换键保存了一个值。如果有,请加载它。如果没有,请将其设置为false(在故事板中,默认情况下将开关设置为false。)每次都会将“开关状态”加载为“关闭”。即使默认值为On。这不应该发生。

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()
    }
}


}

SettingsViewController.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”的默认密钥。它是否正确?或者问题出在代码的其他地方?

2 个答案:

答案 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永远不会被填充。

或者,您可以在视图加载方法上获取值,以便在加载应用时立即获取它。