Swift:UIAlertController 在 while 循环中

Posted

技术标签:

【中文标题】Swift:UIAlertController 在 while 循环中【英文标题】:Swift: UIAlertController inside while loop 【发布时间】:2017-09-10 13:15:35 【问题描述】:

苦于以下代码:

 var connected = false
    while !connected 
        let msg = "Press cancel"
        let alert = UIAlertController(title: "Test", message: msg, preferredStyle: .alert)
        let action = UIAlertAction(title: "Cancel", style: .default)  (action:UIAlertAction) in
            connected = true
        
        alert.addAction(action)
        print ("Hello")
        present(alert, animated: true, completion: nil)

    
    UIAlertController 从未显示,“Hello”被一遍又一遍地打印出来 如果我在 while 子句之后插入“connected = true”,则会显示 UIAlertController,但我无法通过将操作更改为“connected = false”再次显示它

我做错了什么?

【问题讨论】:

你为什么一直在无限循环中显示警报控制器?觉得不合理。保持逻辑只在特定条件下显示警报控制器。 一旦你跳出while循环,它就不会再被执行了。威廉说的是真的,请不要这样做。 嗯,这只是一个例子,我想做的是用户离开应用程序并连接到外部无线网络并有一个“重试”按钮来检查连接是否正常行。因此,我将使用类似“if networkOk connected = true”而不是“connection = true”,如果不行,请再次显示警报控制器... 【参考方案1】:

首先,如 cmets 中所述,在 while 循环中连续显示警报控制器并不是一个好主意。我相信您的预期功能是在 connected 变量变为 false 时显示警报。

要完成此操作,请使用NotificationCenter 回复如下:

viewDidLoad:

NotificationCenter.default.addObserver(self, selector: #selector(ViewController.displayAlert), name: NSNotification.Name(rawValue: "connectionDropped"), object: nil)

willSet 属性观察者添加到connected

var connected: Bool! 
  willSet 
    if newValue == false && oldValue != false 
      NotificationCenter.default.post(name: NSNotification.Name(rawValue: "connectionDropped"), object: nil)
    
  

那么每当你设置self.connected = false,你就会运行这个方法:

@objc func displayAlert() 
  let msg = "Press cancel"
  let alert = UIAlertController(title: "Test", message: msg, preferredStyle: .alert)
  let action = UIAlertAction(title: "Cancel", style: .default)  (action:UIAlertAction) in
    self.connected = true
  
  alert.addAction(action)
  print ("Hello")
  present(alert, animated: true, completion: nil)

只需确保在加载视图层次结构后设置为已连接,例如在viewDidAppear 中。

完成视图后,您可以移除观察者:

deinit 
  NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "connectionDropped"), object: nil)

编辑:

Reachability 框架提供了您需要的功能,尤其是reachabilityChanged 通知。然后,您可以使用我上面概述的类似方法调用displayAlert;这记录在他们的 README 文档中。

【讨论】:

另外,请确保在完成视图后移除观察者。【参考方案2】:
    UIAlertController 从未显示,“Hello”被一遍又一遍地打印出来

在无休止的while 循环中继续显示警报是不合适的,可能会导致面临“AlertController is not in the window hierarchy”问题。

    如果我在 while 子句之后插入“connected = true”,则会显示 UIAlertController,但我无法再次显示它 将操作更改为“connected = false”

当然默认不能再显示了,这段代码已经被执行过了。

解决方案:

显示警报应该与触发特定条件有关,而不是在while 循环中。

例如,如果您打算通知用户设备未连接,您可以使用Reachability 并观察reachabilityChanged 来显示警报,有关更多详细信息,您可以查看库 - 示例 -通知部分。

【讨论】:

【参考方案3】:

我设法通过对函数的递归调用来解决它:

    func showDlg()
    ssid = getWiFiSsid() ?? "AAA"
    ssid = ssid[ssid.startIndex..<ssid.index(ssid.startIndex, offsetBy: 2)]
    if ssid != "GP" 
        print ("SSID: " + ssid)

        let msg = "\nNot connected to GoPro camera\n\nPlease connect to camera wireless network and revert\n "
        alert = UIAlertController(title: "GoPro Golfswing Analyser", message: msg, preferredStyle: .alert)
        let action = UIAlertAction(title: "Try again", style: .default)  (action:UIAlertAction) in
            print("Testing network again")
            self.showDlg()
        
        alert.addAction(action)

        let action1 = UIAlertAction(title: "Cancel", style: .default)  (action:UIAlertAction) in
            print("Cancel - exiting")

        
        alert.addAction(action1)

        present(alert, animated: true, completion: nil)

     else
        print("Connected to GoPro")
    


【讨论】:

以上是关于Swift:UIAlertController 在 while 循环中的主要内容,如果未能解决你的问题,请参考以下文章

Swift:UIAlertController 在 while 循环中

swift UIAlertController使用 UIAlertController的宽度 为270

UiAlertView 或 UiAlertController 在 Swift 中仅显示一次

Swift3:在 SKView 中添加 UIAlertController

在 GameScene 中显示 UIAlertController (SpriteKit/Swift)

如何在 SWIFT 中不执行任何操作就关闭 UIAlertController?