21

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.

Community
  • 1
  • 1
Robert Smith
  • 233
  • 1
  • 2
  • 11

3 Answers3

31

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

crashoverride777
  • 10,581
  • 2
  • 32
  • 56
  • Ive done everything you have said to do but I'm getting "Cannot convert value of type 'UISwitch!.Type' (aka 'ImplicitlyUnwrappedOptional.Type') to expected argument type 'UISwitch!'" and "Cannot convert value of type 'UISwitch!.Type' (aka 'ImplicitlyUnwrappedOptional.Type') to expected argument type 'UISwitch!'" – Robert Smith Sep 29 '16 at 19:42
  • You probably made a mistake in the parameter of switchValueDidChange. Check out this article http://www.ioscreator.com/tutorials/uiswitch-tutorial-in-ios8-with-swift – crashoverride777 Sep 30 '16 at 08:00
  • 1
    In Swift 3, my addTarget() call had to be a bit different: `switch.addTarget(self, action: #selector(switchChanged(switch:)), for: .valueChanged)` – James T Snell Feb 11 '17 at 08:22
  • Hey, thanks for the comment, I just updated my answer for Swift 3. – crashoverride777 Feb 11 '17 at 13:53
  • 1
    Just a minor correction, you need to use underscore in function declaration if you want to use this format : #selector(switchValueDidChange(_:). Otherwise, replace it with parameter name like : #selector(switchValueDidChange(sender:) – KMC Apr 19 '17 at 01:53
10

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")
    }
}
Rehan Ali
  • 428
  • 4
  • 8
DaniChi
  • 301
  • 3
  • 12
4

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
    }


}
Alvin George
  • 14,148
  • 92
  • 64