Swift/UISwitch: how to implement a delegate/listener

空扰寡人 提交于 2020-01-01 01:52:51

问题


In my UITableViewController I have a custom cell which contains a switcher which is the following:

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)

  }
}

I would like to know how to implement a listener/delegate to the switcher in order to get its value from the UITableViewController. I was able to write delegate/listeners for a cell with UITextField and UITextView implementing the methods

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

and

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

but I don't know what I should implement the switcher.


回答1:


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
}



回答2:


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)")
    }



回答3:


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 {

        }
    }



回答4:


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



回答5:


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



回答6:


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


来源:https://stackoverflow.com/questions/32586833/swift-uiswitch-how-to-implement-a-delegate-listener

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!