【问题标题】:UIAlertController keeps segue from performing ("window is not equal to view’s window“)UIAlertController 阻止 segue 执行(“窗口不等于视图的窗口”)
【发布时间】:2019-05-21 11:56:46
【问题描述】:

在我的应用程序中添加UIAlertController 以在执行某些设置时显示进度对话框后,segue 不再执行切换到第二个ViewController (请参阅问题here - 原来是罪魁祸首不是我最初想的那样,这就是为什么我要提出一个新问题)。

所以现在我使用 Swift 5、Xcode 10 和 iOS 12 设置了一个测试项目,我也遇到了同样的问题:

说明:

  • ViewController1:有一个“登录”按钮调用onClickLoginButton
  • NavigationController:通过“segue12”连接到 VC1(我从黄色的“ViewController”图标拖动)
  • ViewController2:我通过“嵌入”将 NC 添加到其中;有一个UITableView
  • 单击“登录”按钮会显示UIAlertController,然后应该执行到VC2 的segue。相反,它只在控制台中输出一条消息(请参阅下面的“控制台输出”)并保持 VC1 加载。

故事板:

ViewController1:

class ViewController: UIViewController {

    @IBOutlet weak var loginButton: UIButton!

    var alert:UIAlertController!
    var alertMessage:String = ""

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func onClickLoginButton(_ sender: Any) {
        setUpDialog()
    }

    private func setUpDialog() {
        alertMessage = "Logging in"
        alert = UIAlertController(title: "Please wait", message: alertMessage, preferredStyle: UIAlertController.Style.alert)
        self.present(alert, animated: true, completion: nil)

        performSegue(withIdentifier: "segue12", sender: self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        print("prepare 1->2a")
        let navVC = segue.destination as? UINavigationController
        let tableVC = navVC?.viewControllers.first as! ViewController2
        tableVC.test = "Test!"
        print("prepare 1->2b")
    }
}

ViewController2:

class ViewController2: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var test:String = ""

    override func viewDidLoad() {
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
        return cell
    }
}

控制台输出:

prepare 1->2a
prepare 1->2b
2019-05-21 13:09:16.981738+0200 SegueTest[3505:69382] <UIView: 0x7fc40fd0e790; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x600000dc3da0>>'s window is not equal to <UIAlertController: 0x7fc41180ba00>'s view's window!

将此添加到prepare(就在print("prepare 1-&gt;2b") 之前)会删除对话框,但它仍会输出消息并且不会切换到第二个视图:

alert.dismiss(animated: true, completion: nil)

上面的消息是什么意思(是什么原因造成的?)以及如何修复这个测试应用程序,使其显示对话框,然后切换到 ViewController2?

【问题讨论】:

  • 你不应该那样做。如果你想要一些please wait 的东西,请使用适当的进度视图(可可豆荚中有很多)而不是 AlertController。我不认为 ALertCOntrollers 应该这样做。如果您在呈现第二个视图之前实际上正在执行一些加载,您应该使用带有completionhandler 的一些进度视图,以便您可以正确关闭进度视图并打开第二个 VC。
  • 不幸的是,没有内置适当的进度视图。我想使用尽可能少的额外库,并且没有必要通过创建我自己的动画视图来重新发明轮子,...如果 AlertController 是已经是内置的东西。您可以在没有按钮的情况下使用它们(没有错误消息/警告),您可以在运行时更改它们的文本(从主/ui线程执行!)并且有一个内置函数可以关闭它并在它消失后执行其他操作(请参阅下面发布的代码 Sh_Khan)。这可能有点不合常规,但它可以工作并且性能很好,所以为什么不呢。 ;)

标签: ios swift segue uialertcontroller


【解决方案1】:

您不能同时显示警报和执行 segue,使用 DispatchQueue.main.asyncAfter 来等待

private func setUpDialog() {
    alertMessage = "Logging in"
    alert = UIAlertController(title: "Please wait", message: alertMessage, preferredStyle: UIAlertController.Style.alert)
    self.present(alert, animated: true, completion: nil)
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        self.alert.dismiss(animated: true, completion: {
            self.performSegue(withIdentifier: "segue12", sender: self)
        })
    }
}

【讨论】:

  • 非常感谢!我真的需要DispatchQueue 吗?我只是在没有在测试应用程序中尝试过它,它仍然有效(这不是“完成”的目的吗?)。您是否也碰巧知道该消息的含义?或者这是这些奇怪的消息之一,没有说明实际问题(比如当插座被搞砸时的“NSInvalidArgumentException”)?
  • 它可以在没有 DispatchQueue.main.asyncAfter 的情况下工作,但您需要在关闭它之前给呈现的等待警报一些时间
  • 啊,我想我明白你的意思了。这只是测试应用程序,所以如果我的实际应用程序显示对话框,然后在几秒钟内执行一些操作(例如读取文件等),然后才将其关闭,则不需要 DispatchQueue,对吧?抱歉,您知道我在问题中发布的消息是什么意思吗?
  • 如果是这样,请确保您这样做是一个后台线程,以免阻止警报的出现,同时发布完整的异常日志以提供帮助
  • 是的,我将/目前使用我一半的代码。也不例外,只有一条消息(“...的窗口不等于...的视图的窗口”)并且应用程序也不会崩溃。我必须用我的真实应用测试你的答案,然后我会看到消息仍在输出。
猜你喜欢
  • 2016-05-11
  • 2014-10-29
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-05
相关资源
最近更新 更多