tda
tda

Reputation: 241

Saving NSUserDefaults with UISwitch in Swift 2

I have posted all my code below to fully demonstrate what I am trying to accomplish. I have a UI Switch, that I would like to save a NSUserDefault on what game mode they would like. I am not sure why this is not working correctly, as it currently does not save- as the switch doesn't work.

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

Code Update:

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

Upvotes: 1

Views: 376

Answers (1)

Eric Aya
Eric Aya

Reputation: 70118

You forgot to actually load the values from NSUserDefaults.

You set them with setValue and setObject, but you never load them back.

Use the valueForKey or objectForKey methods to retrieve your values.

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

Even better with safe unwrapping:

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

A few notes: variables should begin with a lowercase letter, so "MotionMode" should be "motionMode", etc. You could use the specialized object getters like boolForKey instead of the generic objectForKey which forces you to typecast to Bool. Of course it goes with setBool on the other side. Last: the variable you call "MotionMode" actually holds NSUserDefaults.standardUserDefaults(), so I called it "defaults" instead in my example.

Your question has several parts, but it's better to make a single post for a single question. So I've focused about the failing NSUserDefaults part because it was the most important. Using my answer, if your code still doesn't work because of the UI parts, then you should post a new different question about it to keep things clear.

Upvotes: 1

Related Questions