警报不会关闭(警告:尝试从视图控制器关闭...)

时间:2019-08-08 09:25:29

标签: ios swift uialertcontroller xcode11 ios13

因此,我有一个函数可以在Alamofire正在执行某些操作时显示警报,我想在Alamofire完成后关闭该警报,但有时它可以工作,有时却不起作用!并且当它不起作用时,我会收到错误消息( iOS 13,Xcode 11 Beta 5 ): 警告:演示或关闭过程中,尝试从视图控制器(UITabBarController:0x7f90b7013a00)关闭!

这是我用来显示警报的功能:

func showLoadingDialog(show : Bool)  {
        let alert = UIAlertController(title: nil, message: "⏳ Please wait...", preferredStyle: .alert)
        if show == true {


            let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
            loadingIndicator.hidesWhenStopped = true
            loadingIndicator.style = .medium
            loadingIndicator.startAnimating()
            alert.view.addSubview(loadingIndicator)
            present(alert, animated: true, completion: nil)
        } else {
            dismiss(animated: true, completion: nil)
            // I've tried the "alert.dismiss" but it doesn't work!
            //alert.dismiss(animated: true, completion: nil)
            alert.removeFromParent()
        }
    }

我也在使用选项卡栏,并且在其中一个选项卡栏内使用导航控制器,并且在其中使用表格视图,因此当用户单击单元格时,它将转到另一个视图控制器(在同一故事板内部)文件)使用以下代码:

let detailsVC = storyboard?.instantiateViewController(identifier: "Bdetails") as? DetailsController
    self.navigationController?.pushViewController(detailsVC!, animated: true)

然后我也禁用了导航栏(我猜是标题,我正在使用自定义按钮使用以下代码返回预览页面:

self.navigationController?.popViewController(animated: true)

这也是Alamofire,我在其中放置了警报功能,并在viewDidLoad中使用它:

func libHttp(url: String) {

    // Showing the alert.
    showLoadingDialog(show: true)
        Alamofire.request(url).responseJSON { (responseData) ->
            Void in
            if ((responseData.result.value) != nil) {

                let libJSON = JSON(responseData.result.value!)
                if let libData = libJSON.array {
                    for detail in libData {
                        // putting the values into an object from a custom class
                    }

                    // Updates the storyboard elements' value with the objects values.
                    self.update()

                    // dismissing the alert.
                    self.showLoadingDialog(show: false)
                }
            }
        }
    }

3 个答案:

答案 0 :(得分:0)

这似乎是一种竞争条件,涉及到您调用libHttp(url :)函数时的情况。 从导航控制器中弹出viewController后,检查是否有解散警报的情况。

答案 1 :(得分:0)

您的showLoadingDialog(show : Bool)看起来有些奇怪。当传递true来显示警报时,似乎一切都已正确设置,但是传递false来隐藏警报时,您正在创建一个新的UIAlertController,从不实际显示,然后尝试将其删除。 。我猜您真的不想在这里创建新的UIAlertController,而是要删除已经显示的UIAlertController吗?

也许您可以改做类似的事情?

func showLoadingDialog() -> UIAlertController  {
    let alert = UIAlertController(title: nil, message: "⏳ Please wait...", preferredStyle: .alert)
    let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
    loadingIndicator.hidesWhenStopped = true
    loadingIndicator.style = .medium
    loadingIndicator.startAnimating()
    alert.view.addSubview(loadingIndicator)
    present(alert, animated: true, completion: nil)
    return alert
}

func libHttp(url: String) {

    // Showing the alert.
    let alert = showLoadingDialog()
    Alamofire.request(url).responseJSON { (responseData) ->
        Void in
        if ((responseData.result.value) != nil) {

            let libJSON = JSON(responseData.result.value!)
            if let libData = libJSON.array {
                for detail in libData {
                    // putting the values into an object from a custom class
                }

                // Updates the storyboard elements' value with the objects values.
                self.update()

                // dismissing the alert.
                alert.dismiss(animated: true, completion: nil)
            }
        }
    }
}

答案 2 :(得分:0)

您的alert.dismiss调用不起作用,因为每次调用showLoadingDialog时都要实例化一个新的AlertController。

这是一个最低限度的可行示例:

import UIKit

class ViewController: UIViewController {
    let alert = UIAlertController(title: nil, message: "⏳ Please wait...", preferredStyle: .alert)

    func showLoadingDialog(show : Bool) {
        if show {
            let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
            loadingIndicator.hidesWhenStopped = true
            loadingIndicator.style = .medium
            loadingIndicator.startAnimating()
            alert.view.addSubview(loadingIndicator)
            present(alert, animated: true, completion: nil)
        } else {
            alert.dismiss(animated: true, completion: nil)
        }
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        showLoadingDialog(show: true)

        DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
            self.showLoadingDialog(show: false)
        }
    }
}

模拟器预览:

Simulator Preview