在 Swift 2 中使用 UISwitch 保存 NSUserDefaults

Saving NSUserDefaults with UISwitch in Swift 2

我已经在下面发布了我的所有代码,以充分展示我想要完成的事情。我有一个 UI 开关,我想保存一个 NSUserDefault 以了解他们想要的游戏模式。我不确定为什么这不能正常工作,因为它目前没有保存——因为开关不起作用。

import SpriteKit

class ModeScene: SKScene {

    var modeSwitch = UISwitch()
    var motionLabel = UILabel()
    var touchLabel = UILabel()

    override func didMoveToView(view: SKView) {
        let MotionMode = NSUserDefaults.standardUserDefaults()
        let TouchMode = NSUserDefaults.standardUserDefaults()

        modeSwitch.center = CGPoint(x: view.center.x, y: view.frame.size.height / 1.3)
        modeSwitch.addTarget(self, action: Selector("updateMode"), forControlEvents: UIControlEvents.ValueChanged)
        if TouchMode {
            modeSwitch.on = false
        }
        else{
            modeSwitch.on = true
        }
        self.view?.addSubview(modeSwitch)

        motionLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 700, height: 200))
        motionLabel.center = CGPoint(x: view.center.x * 3.4, y: view.frame.size.height / 1.3)
        motionLabel.text = "Accelerometer"
        motionLabel.textColor = UIColor.whiteColor()
        motionLabel.font = UIFont(name:"ArialRoundedMTBold", size: 16)
        self.view?.addSubview(motionLabel)

        touchLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 700, height: 200))
        touchLabel.center = CGPoint(x: view.center.x * 2.25, y: view.frame.size.height / 1.3)
        touchLabel.text = "Touch To Move"
        touchLabel.textColor = UIColor.whiteColor()
        touchLabel.font = UIFont(name:"ArialRoundedMTBold", size: 16)
        self.view?.addSubview(touchLabel)

        DoneBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 400, height: 30))
        DoneBtn.center = CGPoint(x: view.center.x * 1.7, y: view.frame.size.height / 14)
        DoneBtn.setTitle("Done", forState: UIControlState.Normal)
        DoneBtn.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
        DoneBtn.addTarget(self, action: Selector("done"), forControlEvents: UIControlEvents.TouchUpInside)
        self.view?.addSubview(DoneBtn)

        updateMode()

    }

    func updateMode(){
        if modeSwitch.on {
            // mode is accel
            let MotionMode = NSUserDefaults.standardUserDefaults()
            MotionMode.setValue(true, forKey: "MotionMode")
            NSLog("Mode is accel")

        }
        else{
            // mode is touch
            let TouchMode = NSUserDefaults.standardUserDefaults()
            TouchMode.setObject(true, forKey: "TouchMode")
            NSLog("Mode is touch")
        }
    }

    func done(){
        self.scene?.view?.presentScene(StartScene(size: self.scene!.size), transition: SKTransition.fadeWithColor(UIColor.blackColor(), duration: 1))
        headerLabel.removeFromSuperview()
        DoneBtn.removeFromSuperview()
        modeSwitch.removeFromSuperview()
        touchLabel.removeFromSuperview()
        motionLabel.removeFromSuperview()
    }
}

代码更新:

import SpriteKit

class ModeScene: SKScene {

    var modeSwitch = UISwitch()
    var motionLabel = UILabel()
    var touchLabel = UILabel()
    var DoneBtn : UIButton!

    override func didMoveToView(view: SKView) {

        backgroundColor = SKColor.blackColor()

        modeSwitch.center = CGPoint(x: view.center.x, y: view.frame.size.height / 1.3)
        modeSwitch.addTarget(self, action: Selector("updateMode"), forControlEvents: UIControlEvents.ValueChanged)
        self.view?.addSubview(modeSwitch)

        motionLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 700, height: 200))
        motionLabel.center = CGPoint(x: view.center.x * 3.4, y: view.frame.size.height / 1.3)
        motionLabel.text = "Accelerometer"
        motionLabel.textColor = UIColor.whiteColor()
        motionLabel.font = UIFont(name:"ArialRoundedMTBold", size: 16)
        self.view?.addSubview(motionLabel)

        touchLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 700, height: 200))
        touchLabel.center = CGPoint(x: view.center.x * 2.25, y: view.frame.size.height / 1.3)
        touchLabel.text = "Touch To Move"
        touchLabel.textColor = UIColor.whiteColor()
        touchLabel.font = UIFont(name:"ArialRoundedMTBold", size: 16)
        self.view?.addSubview(touchLabel)

        DoneBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 400, height: 30))
        DoneBtn.center = CGPoint(x: view.center.x * 1.7, y: view.frame.size.height / 14)
        DoneBtn.setTitle("Done", forState: UIControlState.Normal)
        DoneBtn.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
        DoneBtn.addTarget(self, action: Selector("done"), forControlEvents: UIControlEvents.TouchUpInside)
        self.view?.addSubview(DoneBtn)


        let defaults = NSUserDefaults.standardUserDefaults()
        if let motionMode = defaults.objectForKey("motionMode") as? Bool {
            if motionMode {
                // true
                modeSwitch.on = true
            } else {
                // false
                modeSwitch.on = false
            }
        }

        updateMode()

    }


    func updateMode(){
        let defaults = NSUserDefaults.standardUserDefaults()
        if modeSwitch.on {
            // mode is accel
            defaults.setBool(true, forKey: "motionMode")
            NSLog("Mode is accel")

        }
        else{
            // mode is touch
            defaults.setBool(true, forKey: "touchMode")
            NSLog("Mode is touch")
        }
    }


    func done(){
        self.scene?.view?.presentScene(StartScene(size: self.scene!.size), transition: SKTransition.fadeWithColor(UIColor.blackColor(), duration: 1))
        headerLabel.removeFromSuperview()
        DoneBtn.removeFromSuperview()
        modeSwitch.removeFromSuperview()
        touchLabel.removeFromSuperview()
        motionLabel.removeFromSuperview()
    }
}

您忘记实际加载 NSUserDefaults 中的值。

你用 setValuesetObject 设置它们,但你永远不会加载它们。

使用 valueForKeyobjectForKey 方法检索您的值。

let defaults = NSUserDefaults.standardUserDefaults()
let MotionMode = defaults.objectForKey("MotionMode") as! Bool
if MotionMode {
    // true
} else {
    // false
}

安全解包更好:

let defaults = NSUserDefaults.standardUserDefaults()
if let MotionMode = defaults.objectForKey("MotionMode") as? Bool {
    if MotionMode {
        // true
    } else {
        // false
    }
}

一些注意事项:变量应该以小写字母开头,所以 "MotionMode" 应该是 "motionMode",等等。你可以使用像 boolForKey 这样的专用对象 getter 而不是通用的objectForKey 这会强制您将类型转换为 Bool。当然,另一边是 setBool。最后:您调用 "MotionMode" 的变量实际上包含 NSUserDefaults.standardUserDefaults(),所以我在示例中将其称为 "defaults"。

你的问题有几个部分,但最好把一个问题做成一个post。所以我关注失败的 NSUserDefaults 部分,因为它是最重要的。使用我的回答,如果您的代码由于 UI 部分仍然无法正常工作,那么您应该 post 一个新的不同的问题来保持清晰。