【发布时间】:2017-03-03 22:17:46
【问题描述】:
我刚刚注意到在其 IBAction 中设置 UISwitch 的 isOn 会导致再次调用 IBAction。所以下面的代码:
class ViewController: UIViewController {
var count = 0
@IBOutlet weak var mySwitch: UISwitch!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
mySwitch.isOn = false
}
@IBAction func buttonTapped(_ sender: UIButton) {
mySwitch.isOn = !mySwitch.isOn
}
@IBAction func switchChanged(_ sender: UISwitch) {
print("\(count) pre: \(mySwitch.isOn)")
mySwitch.isOn = !mySwitch.isOn
print("\(count) post: \(mySwitch.isOn)")
count += 1
}
}
当开关打开一次时打印以下内容:
0 pre: true
0 post: false
1 pre: false
1 post: true
- 开关在
viewDidLoad中关闭 - 开关被用户打开
- 当
switchChanged(IBAction) 被调用时,开关现在打开 -
0 pre: true已打印 - 开关在
switchChanged中以编程方式关闭 -
0 post: false已打印 -
系统再次调用
switchChanged - 现在
switchChanged中的开关已关闭,并且调用了1 pre: false - 以编程方式打开开关
-
1 post: true已打印
为什么系统会第二次调用 IBAction?例如,当想要基于某种内部状态否定用户的操作时,如何解决这个问题?我觉得我遗漏了一些非常明显的东西,但我很确定类似的代码曾经可以工作。这是iOS错误吗?它在 iOS 10.2 iPhone 5s 模拟器 Xcode 版本 8.2.1 (8C1002) 上运行
有趣的是,当点击绑定到buttonTapped 的按钮时(调用相同的方法),不会调用开关的 IBAction。
【问题讨论】:
-
您可能已将 switch 事件处理程序连接到两个不同的事件。
-
我对其进行了测试,并看到了与您相同的行为。仅当您通过点击它来更改开关时,通过拖动它来更改它只会导致该操作被调用一次。
-
在
switchChanged中切换开关没有意义。如果您希望开关关闭,请将其显式设置为关闭,然后再次调用该方法无关紧要,因为第二次它将关闭并且您将其设置为关闭并且不会被调用再次。 -
gnasher729,我确实考虑过不止一个事件可以连接到交换机,但事实并非如此。丹,我确认了您在拖动开关时看到的内容。即,通过拖动来更改开关,IBAction 被调用一次,“撤消”就像我最初预期的那样工作。
-
Paulw,如果我只是想让它关闭,也许这会奏效,但如果我真的想将它切换回初始状态怎么办,问题仍然在于为什么该方法被调用两次。此外,如果以编程方式设置 isOn 导致该方法被调用一次,为什么它不继续被调用?
标签: ios