在 swift for iOs 中,我有一个 if / else 代码块,对 UISwitch 中的更改做出反应。在某些情况下如何将 uiswitch 设置回关闭状态?

In swift for iOs,I have an if / else block of code, reacting to changes in a UISwitch. How to set the uiswitch back to off in some situations?

在我的 swift iOS 应用程序中,我有一个简单的 UISwitch 控件。我已将值更改插座连接到我的@IBAction。代码如下所示:

@IBAction func userDidSelectVisibiltySwitch(_ sender: Any) {

    if self.visibilitySwitch.isOn {
       if badCondition {
           self.visibilitySwith.setOn(false, animated: false)

          return
       }
     } else { // Strangely, it executes the else (I think because the compiler is evaluating the isOn condition again when it arrives to the else {}
        // work to be done if the user has turned off the switch
     }
}

我怀疑在这种情况下,由于我在计算 else 之前关闭开关,编译器会执行 else {} 语句,因为它再次计算上面的 isOn 表达式。但是,鉴于我放置了 'return' 指令,这怎么可能呢?那真的超出了我。我的嫌疑人的确认来自于这样一个事实,即如果我 dispatch_async 使用 GCD 'self.visibilitySwith.setOn(false, animated: false)' 语句,它可以正常工作而无需执行 else {} 语句,因为 else 的评估发生在控制之前被我的声明关闭了。我的代码现在看起来像这样,并且有效:

@IBAction func userDidSelectVisibiltySwitch(_ sender: Any) {

    if self.visibilitySwitch.isOn {
       if badCondition {
            DispatchQueue.main.async {
               self.visibilitySwith.setOn(false, animated: false)
            }
            return
       }
     } else { // In this case it is normal, it does not execute the else {}
        // work to be done if the user has turned off the switch
     }
}

我认为在这种情况下我遗漏了 swift 的重要内容。任何帮助是极大的赞赏。我已经提供了解决方案,但我想了解问题所在。非常感谢

您不是通过 sender 参数访问 UISwitch,而是直接访问我假设的 IBOutlet 值。除了这种方法,您还可以访问发件人,如下所述:

@IBAction func userDidSelectVisibiltySwitch(_ sender: UISwitch) {
    if sender.isOn && badCondition {
        sender.setOn(false, animated: false)
    } else { // In this case it is normal, it does not execute the else {}
        // work to be done if the user has turned off the switch
    }
}

您的修复工作的原因可能是调度调用引入了轻微延迟,允许 IBOutlet 值更新其值。

我也结合了你的 if 声明,因为你提供的示例不需要嵌套检查。

根据 RMADDY 的评论更新

这个解决方案让我有点代码味,经过进一步调查,我能够重现 OP 描述的场景。这是通过在 Storyboard 中设置动作来完成的,如下所示:

使用该设置,我看到了以下内容:

  • OP 发布的原始代码会失败
  • 如 OP 所示添加 DispatchQueue 会在短暂延迟后更正开关
  • 我发布的解决方案可以正常工作

假设这是 OP 所做的,那么第一个更正就是将事件更改为 Value Changed。然后,正如 rmaddy 在评论中所述,无论您使用参数还是 IBOutlet,这都会成功。根据原问题,我的解释是界面上的outlet value和switch状态不同步的问题。