UISwitch: Swift 3: Programmatically

Updated to swift 5

override func didMoveToView(view: SKView) {
    /* Setup your scene here */
    let switchDemo = UISwitch(frame:CGRect(x: 150, y: 300, width: 0, height: 0))
    switchDemo.isOn = true
    switchDemo.setOn(true, animated: false)
    switchDemo.addTarget(self, action: #selector(switchValueDidChange(_:)), for: .valueChanged)
    self.view!.addSubview(switchDemo)
}

Helper method:

@objc func switchValueDidChange(_ sender: UISwitch!) {
    if (sender.isOn){
        print("on")
    }
    else{
        print("off")
    }
}

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


With parameter:

@IBOutlet var categorySwitch:UISwitch!

var categorySwitchIsOn:Bool =  false

On viewDidLoad:

  override func viewDidLoad() {
        super.viewDidLoad()
        categorySwitch.addTarget(self, action:#selector(ViewController.categorySwitchValueChanged(_:)), for: .valueChanged)
    }

Associated function:

func categorySwitchValueChanged(_ sender : UISwitch!){

    if sender.isOn {
        categorySwitchIsOn =  true

    } else {

        categorySwitchIsOn =  false
    }


}