web-dev-qa-db-fra.com

Swift / UISwitch: comment implémenter un délégué / écouteur

Dans mon UITableViewController, j'ai une cellule personnalisée qui contient un commutateur qui est le suivant:

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)

  }
}

Je voudrais savoir comment implémenter un écouteur/délégué au commutateur afin d'obtenir sa valeur à partir de UITableViewController. J'ai pu écrire des délégués/écouteurs pour une cellule avec UITextField et UITextView implémentant les méthodes

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

et

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

mais je ne sais pas ce que je dois implémenter le commutateur.

21
SagittariusA

UISwitch n'a pas de protocole délégué. Vous pouvez écouter l'état comme suit:

ObjC:

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


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

Rapide:

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
}
65
Daniel

Dans Swift4.

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)")
    }
10
Mujahid Latif

Swift 3:

Utilisation de la mise en page automatique du storyboard:

Ajouter une référence:

@IBOutlet weak var sampleSwitch: UISwitch!

Méthode associée:

@IBAction func sampleSwitchValueChanged(_ sender: Any) {

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

Manière programmatique:

Ajout d'une cible:

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

La méthode associée au commutateur:

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

            print("switch on")

        } else {

        }
    }
7
A.G

Une autre ( Swift 3 ou 4 ) consiste à utiliser didSet observer et à réduire considérablement le code, comme ceci -

Dans la déclaration de classe, déclarez une variable comme ci-dessous:

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

Ensuite, vous pouvez avoir un IBAction sur le UISwitch comme ça

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

J'ai la solution en objectif-c, c'est la méthode que j'utilise régulièrement:

-L'action du commutateur doit être dans le contrôleur de table et non sur la cellule

-Lorsque vous appuyez sur le commutateur à l'intérieur de l'action, vous pouvez le faire pour trouver la bonne cellule, alors vous pouvez facilement trouver l'index ou toute autre valeur dont vous avez besoin ...

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

la méthode findSuperviewWithClass est une catégorie sur 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
Mattia Lancieri

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
    }
}
2
David Seek