问题
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