简体   繁体   English

斯威夫特:while循环内的UIAlertController

[英]Swift: UIAlertController inside while loop

Struggling with the following code: 努力与以下代码:

 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)

    }
  1. The UIAlertController is never shown, "Hello" is printed over and over again 从不显示UIAlertController,一遍又一遍地打印“ Hello”
  2. If I insert "connected = true" after the while clause then the UIAlertController is shown, but I'm not able to show it again by changing the action to "connected = false" 如果我在while子句后插入“ connected = true”,则显示UIAlertController,但是我无法通过将操作更改为“ connected = false”来再次显示它

What am I doing wrong? 我究竟做错了什么?

First of all, as mentioned in the comments, its not a good idea to present your alert controller continuously in a while loop. 首先,如评论中所述,在while循环中连续显示警报控制器不是一个好主意。 I believe your intended functionality is to display an alert whenever the connected variable becomes false. 我相信您想要的功能是在connected变量变为false时显示警报。

To accomplish this use NotificationCenter to respond as follows: 为此,请使用NotificationCenter进行以下响应:

In viewDidLoad : viewDidLoad

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

Add a willSet property observer to connected : connected添加一个willSet属性观察connected

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

Then whenever you set self.connected = false , you will run this method: 然后,每当您设置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)
}

Just make sure you set connected after the view hierarchy has been loaded eg in viewDidAppear . 只需确保在加载视图层次结构后将连接设置为已设置,例如在viewDidAppear

Once you're done with the view you can then remove the observer: 一旦完成了视图,就可以删除观察者:

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

EDIT: 编辑:

The functionality you need is provided with the Reachability framework, in particular with the reachabilityChanged notification. 您需要的功能随“ 可达性”框架一起提供,尤其是在reachabilityChanged通知中。 You can then call the displayAlert using a similar approach that I outlined above; 然后,可以使用我上面概述的类似方法来调用displayAlert this is documented on their README document. 这记录在他们的自述文件中。

  1. The UIAlertController is never shown, "Hello" is printed over and over again 从不显示UIAlertController,一遍又一遍地打印“ Hello”

It is inappropriate to keep presenting the alert in an endless while loop, probably, it leads to facing " AlertController is not in the window hierarchy " issue. 始终在无尽的while循环中呈现警报是不合适的 ,可能会导致面临“ AlertController不在窗口层次结构中 ”的问题。

  1. If I insert "connected = true" after the while clause then the UIAlertController is shown, but I'm not able to show it again by changing the action to "connected = false" 如果我在while子句后插入“ connected = true”,则显示UIAlertController,但是我无法通过将操作更改为“ connected = false”来再次显示它

Of course you won't be able to show it again by default, the chunk of code is already been executed. 当然,默认情况下您将无法再次显示它,因为代码块已被执行。

Solution: 解:

Presenting the alert should be related to triggering a specific condition, not in a while loop. 呈现警报应该与触发特定条件有关,而不是在while循环中。

For instance, if you are aiming to notify the user that the device is unconnected, You could use Reachability and observe reachabilityChanged to present the alert, for more details you could check the library - Example - notifications section. 例如,如果您打算通知用户设备未连接,则可以使用“ 可达性”并观察“ reachabilityChanged来显示警报,有关更多详细信息,请查看库- 示例-通知部分。

I managed to solve it using a recursive call to the function: 我设法通过递归调用该函数来解决它:

    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")
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM