Swift / UISwitch: cómo implementar un delegado / oyente

En mi UITableViewController tengo una celda personalizada que contiene un switcher whoce es la siguiente:

import Foundation import UIKit class SwitchCell: UITableViewCell { @IBOutlet weak var label : UILabel! @IBOutlet weak var switchEmail : UISwitch! func setEditable(canEdit:Bool) { if (canEdit) { self.switchEmail.enabled = true self.label.highlighted = false } else { self.switchEmail.enabled = false self.label.highlighted = true } } func configureCellWithSwitch(labelText:String, switchValue:Bool, enabled:Bool) { var labelFrame:CGRect = self.label.frame labelFrame.size.height = Settings.labelHeight self.label.frame = labelFrame self.label.text = labelText if (switchValue) { self.switchEmail.setOn(true, animated: true) } else { self.switchEmail.setOn(false, animated: true) } self.setEditable(enabled) } } 

Me gustaría saber cómo implementar un oyente / delegado en el conmutador para get su valor del UITableViewController. Pude escribir delegado / oyentes para celda con UITextField y UITextView implementando los methods

 func controller(controller: UITableViewCell, textViewDidEndEditing: String, atIndex: Int) 

y

 func controller(controller: UITableViewCell, textFieldDidEndEditingWithText: String, atIndex: Int) 

pero no sé qué debo implementar para el conmutador.

UISwitch no tiene protocolo de delegado. Puede escuchar el estado de la siguiente manera:

ObjC:

 // somewhere in your setup: [self.mySwitch addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged]; - (void)switchChanged:(UISwitch *)sender { // Do something BOOL value = sender.on; } 

Rápido:

 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 } 

Swift 3:

Uso de Storyboard Autolayout:

Añadir reference:

 @IBOutlet weak var sampleSwitch: UISwitch! 

Método asociado:

 @IBAction func sampleSwitchValueChanged(_ sender: Any) { if sampleSwitch.isOn { print("ON") } else { print ("OFF") } } 

Forma programática:

Agregar objective:

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

El método asociado con el interruptor:

  func sampleSwitchValueChanged(sender: UISwitch!) { if sender.isOn { print("switch on") } else { } } 

Tengo la solución en objective-c, es el método que uso regularmente:

-La acción del interruptor debe estar en tableviewcontroller y no en la celda

-Cuando toque el interruptor dentro de la acción puede hacer esto para encontrar la celda correcta, entonces puede encontrar fácilmente el índice o cualquier otro valor que necesite …

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

el método findSuperviewWithClass es una categoría en 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 } } 

Otro método ( Swift 3 o 4 ) es usar el observador didSet y networkingucir drásticamente el código,

En la statement de class, declare una variable como a continuación:

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

Entonces puedes tener una IBAction en el UISwitch como tal

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