2015-09-15 14 views
9

Nel mio UITableViewController ho un cellulare personalizzato che contiene un whoce switcher è la seguente:Swift/UISwitch: come implementare un delegato/ascoltatore

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) 

    } 
} 

Vorrei sapere come implementare un ascoltatore/delegato allo switcher per ottenere il suo valore da UITableViewController. Sono stato in grado di scrivere delegato/ascoltatori per cella con UITextField e UITextView attuazione dei metodi

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

e

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

ma non so che cosa devo implementare per lo switcher.

risposta

29

UISwitch non ha protocollo delegato. È possibile ascoltare lo stato come segue:

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 
    } 
+0

Ok, questo è ciò che ho appena scritto all'interno della cellula classe nel init(). Mi piacerebbe sapere come posso recuperare il valore dello switch dal mio controller di visualizzazione tabella ... quale metodo dovrei implementare lì? –

+1

@LoryLory vedere il mio aggiornamento: il valore di 'UISwitch' è disponibile tramite' .on' – Daniel

+0

Ah ok, quel metodo dovrebbe essere all'interno del TableView giusto? Ho pensato che fosse all'interno della cella della classe personalizzata ... ecco perché non sapevo come ottenere il valore dal controller della vista tabella –

2

ho la soluzione in Objective-C, si è il metodo che uso regolarmente:

-L'azione dell'interruttore deve essere in tableviewcontroller e non nella cella

-Quando si tocca l'interruttore all'interno dell'azione, è possibile farlo per trovare la cella corretta, quindi è possibile trovare facilmente l'indice o qualsiasi altro valore di cui hai bisogno ...

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

il metodo findSuperviewWithClass è una categoria in 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; 
} 
2

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 
    } 
} 
5

Swift 3:

Utilizzando Storyboard Autolayout:

Aggiungi riferimento:

@IBOutlet weak var sampleSwitch: UISwitch! 

metodo Associate:

@IBAction func sampleSwitchValueChanged(_ sender: Any) { 

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

modo programmatico:

Aggiunta di destinazione:

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

Il metodo associato all'interruttore:

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

      print("switch on") 

     } else { 

     } 
    } 
1

Altro (Swift 3 o 4) metodo consiste nell'utilizzare didSet osservatore e ridurre drasticamente il codice, come cd

Nella classe dichiarazione dichiarare una variabile come di seguito:

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

Quindi si può avere un IBAction sul UISwitch in questo modo

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