Swift/UISwitch:如何实现一个delegate/listener
Swift/UISwitch: how to implement a delegate/listener
在我的 UITableViewController 中,我有一个自定义单元格,其中包含一个切换器,如下所示:
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)
}
}
我想知道如何为切换器实现 listener/delegate 以便从 UITableViewController 获取它的值。我能够使用 UITextField 和 UITextView 实现方法 delegate/listeners 为单元格编写
func controller(controller: UITableViewCell, textViewDidEndEditing: String, atIndex: Int)
和
func controller(controller: UITableViewCell, textFieldDidEndEditingWithText: String, atIndex: Int)
但我不知道应该如何实现切换器。
UISwitch
没有委托协议。您可以通过以下方式收听状态:
对象:
// 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
}
我在objective-c中有解决方法,是我常用的方法:
-开关的Action必须在tableviewcontroller中,不能在cell中
-当您点击动作中的开关时,可以执行此操作以找到正确的单元格,然后您可以轻松找到索引或您需要的任何其他值...
- (IBAction)switchValueChanged:(UISwitch *)sender
{
YourCellClass *cell = (YourCellClass *)[sender findSuperViewWithClass:[YourCellClass class]];
etc....
}
方法 findSuperviewWithClass 是 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
}
}
Swift 3:
使用故事板自动布局:
添加参考:
@IBOutlet weak var sampleSwitch: UISwitch!
关联方法:
@IBAction func sampleSwitchValueChanged(_ sender: Any) {
if sampleSwitch.isOn {
print("ON")
}
else {
print ("OFF")
}
}
编程方式:
添加目标:
sampleSwitch.addTarget(self, action: #selector(ViewController.sampleSwitchValueChanged(sender:)), for: UIControlEvents.valueChanged)
与开关关联的方法:
func sampleSwitchValueChanged(sender: UISwitch!)
{
if sender.isOn {
print("switch on")
} else {
}
}
另一种(Swift 3 or 4)方法是使用didSet
观察者并大幅减少代码, 像这样-
在 class 声明中声明如下变量:
var switchFlag: Bool = false {
didSet{ //This will fire everytime the value for switchFlag is set
print(switchFlag) //do something with the switchFlag variable
}
}
然后你可以在 UISwitch
上有一个 IBAction
像这样
@IBAction func switchChanged(_ sender: Any) {
if self.mySwitch.isOn{
switchFlag = true
}else{
switchFlag = false
}
}
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)")
}
在Swift5
switchDemo.addTarget(self, action: #selector(didTapAdvertise), for:UIControl.Event.valueChanged)
@objc func didTapAdvertise(mySwitch: UISwitch) {
let value = mySwitch.isOn
// Do something
print("switch value changed \(value)")
}
在我的 UITableViewController 中,我有一个自定义单元格,其中包含一个切换器,如下所示:
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)
}
}
我想知道如何为切换器实现 listener/delegate 以便从 UITableViewController 获取它的值。我能够使用 UITextField 和 UITextView 实现方法 delegate/listeners 为单元格编写
func controller(controller: UITableViewCell, textViewDidEndEditing: String, atIndex: Int)
和
func controller(controller: UITableViewCell, textFieldDidEndEditingWithText: String, atIndex: Int)
但我不知道应该如何实现切换器。
UISwitch
没有委托协议。您可以通过以下方式收听状态:
对象:
// 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
}
我在objective-c中有解决方法,是我常用的方法:
-开关的Action必须在tableviewcontroller中,不能在cell中
-当您点击动作中的开关时,可以执行此操作以找到正确的单元格,然后您可以轻松找到索引或您需要的任何其他值...
- (IBAction)switchValueChanged:(UISwitch *)sender
{
YourCellClass *cell = (YourCellClass *)[sender findSuperViewWithClass:[YourCellClass class]];
etc....
}
方法 findSuperviewWithClass 是 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
}
}
Swift 3:
使用故事板自动布局:
添加参考:
@IBOutlet weak var sampleSwitch: UISwitch!
关联方法:
@IBAction func sampleSwitchValueChanged(_ sender: Any) {
if sampleSwitch.isOn {
print("ON")
}
else {
print ("OFF")
}
}
编程方式:
添加目标:
sampleSwitch.addTarget(self, action: #selector(ViewController.sampleSwitchValueChanged(sender:)), for: UIControlEvents.valueChanged)
与开关关联的方法:
func sampleSwitchValueChanged(sender: UISwitch!)
{
if sender.isOn {
print("switch on")
} else {
}
}
另一种(Swift 3 or 4)方法是使用didSet
观察者并大幅减少代码, 像这样-
在 class 声明中声明如下变量:
var switchFlag: Bool = false {
didSet{ //This will fire everytime the value for switchFlag is set
print(switchFlag) //do something with the switchFlag variable
}
}
然后你可以在 UISwitch
上有一个 IBAction
像这样
@IBAction func switchChanged(_ sender: Any) {
if self.mySwitch.isOn{
switchFlag = true
}else{
switchFlag = false
}
}
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)")
}
在Swift5
switchDemo.addTarget(self, action: #selector(didTapAdvertise), for:UIControl.Event.valueChanged)
@objc func didTapAdvertise(mySwitch: UISwitch) {
let value = mySwitch.isOn
// Do something
print("switch value changed \(value)")
}