Swift/UISwitch: how to implement a delegate/listener

别来无恙 提交于 2019-12-03 05:42:37
Daniel

UISwitch has no delegate protocol. You can listen to the status as follows:

ObjC:

// somewhere in your setup:
[self.mySwitch addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];


- (void)switchChanged:(UISwitch *)sender {
   // Do something
   BOOL value = sender.on;
}

Swift:

mySwitch.addTarget(self, action: "switchChanged:", forControlEvents: UIControlEvents.ValueChanged)

func switchChanged(mySwitch: UISwitch) {
   let value = mySwitch.on
   // Do something
}

Swift3 :

mySwitch.addTarget(self, action: #selector(switchChanged), for: UIControlEvents.valueChanged)

func switchChanged(mySwitch: UISwitch) {
    let value = mySwitch.isOn
    // Do something
}

Swift4:

mySwitch.addTarget(self, action: #selector(switchChanged), for: UIControl.Event.valueChanged)

@objc func switchChanged(mySwitch: UISwitch) {
    let value = mySwitch.isOn
    // Do something
}

In Swift4.0

mySwitch.addTarget(self, action: #selector(valueChange), for:UIControlEvents.valueChanged)

 @objc func valueChange(mySwitch: UISwitch) {
        let value = mySwitch.isOn
        // Do something
        print("switch value changed \(value)")
    }

Swift 3:

Using Storyboard Autolayout:

Add Reference:

@IBOutlet weak var sampleSwitch: UISwitch!

Associate method:

@IBAction func sampleSwitchValueChanged(_ sender: Any) {

    if sampleSwitch.isOn {
        print("ON")  
    }
    else {
        print ("OFF")
    }
}

Programatic way:

Adding Target:

sampleSwitch.addTarget(self, action: #selector(ViewController.sampleSwitchValueChanged(sender:)), for: UIControlEvents.valueChanged)

The method associated with the switch:

   func sampleSwitchValueChanged(sender: UISwitch!)
    {
        if sender.isOn {

            print("switch on")

        } else {

        }
    }

Another (Swift 3 or 4) method is to use didSet observer and drastically reduce code, like so-

In the class declaration declare a variable like below:

var switchFlag: Bool = false {
        didSet{               //This will fire everytime the value for switchFlag is set
            print(switchFlag) //do something with the switchFlag variable
        }
    }

Then you can have an IBAction on the UISwitch like so

@IBAction func switchChanged(_ sender: Any) {
        if self.mySwitch.isOn{
            switchFlag = true
        }else{
            switchFlag = false
        }
    }

I have the solution in objective-c, it is the method that I use regularly:

-The Action of the switch must be in tableviewcontroller and not on the cell

-When You tap on the switch inside the action can do this to find the correct cell, then you can easily find the index or any other value that you need ...

- (IBAction)switchValueChanged:(UISwitch *)sender
{
    YourCellClass *cell = (YourCellClass *)[sender findSuperViewWithClass:[YourCellClass class]];
        etc....
    }

the method findSuperviewWithClass is a category on UIView

- (UIView *)findSuperViewWithClass:(Class)superViewClass
{
    UIView *superView = self.superview;
    UIView *foundSuperView = nil;

    while (nil != superView && nil == foundSuperView)
    {
        if ([superView isKindOfClass:superViewClass])
        {
            foundSuperView = superView;
        } else
        {
            superView = superView.superview;
        }
    }
    return foundSuperView;
}

Swift 3:

@IBOutlet weak var mySwitch: UISwitch!  

mySwitch.addTarget(self, action: #selector(MyClass.switchChanged(_:)), for: UIControlEvents.valueChanged)

func switchChanged(_ mySwitch: UISwitch) {
    if mySwitch.isOn {
        // handle on
    } else {
        // handle off
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!