UISwitch: Swift 3: Programmatically

Robert Smith picture Robert Smith · Sep 29, 2016 · Viewed 31.5k times · Source

How can I programmatically add a uiswitch and call an action when on and one when off? Ive been searching for hours now. Can I please have some help? I know how to add the switch but it stays on the screen no matter what scene I'm on. So far, I've been able to add the button and make it switch from on to off, but for some reason the switch just says on the screen in every scene. I was lost after that so I followed this; from How to programmatically put a UISwitch in a SpriteKit/Skcene

Yes it is possible. Just use this code in your SKScene class:

override func didMoveToView(view: SKView) {
    /* Setup your scene here */
    let switchDemo = UISwitch(frame:CGRectMake(150, 300, 0, 0))
    switchDemo.on = true
    switchDemo.setOn(true, animated: false)
    switchDemo.addTarget(self, action: "switchValueDidChange:", forControlEvents: .ValueChanged)
    self.view!.addSubview(switchDemo)
}

Helper method:

func switchValueDidChange(sender:UISwitch!)
{
    if (sender.on == true){
        print("on")
    }
    else{
        print("off")
    }
}

I kept getting errors so I did what Xcode suggested which ended up with the SIGBART error.

Answer

crashoverride777 picture crashoverride777 · Sep 29, 2016

You are calling the selector wrong on the addTarget action line. They finally changed it at one point in Swift 2 to get rid of using strings for selector method calls, which now makes them a lot less error prone.

Change it to this (Swift 3 syntax)

switchDemo.addTarget(self, action: #selector(switchValueDidChange(_:)), for: .valueChanged)

You basically call #selector in the action parameter and include the method you want to call, in your case switchValueDidChange. Note the (_:) syntax at the end, thats indicating that the method you want to call takes a parameter, in your case a UISwitch.

 func switchValueDidChange(_ sender: UISwitch) {
     ...
 }

If you want to call a regular method that takes no parameters e.g

 func switchValueDidChange() {
 }

than you would just say

switchDemo.addTarget(self, action: #selector(switchValueDidChange), for: .valueChanged)

without the (_:) syntax.

Hope this helps