简体   繁体   English

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

[英]Alert won't dismiss (Warning: Attempt to dismiss from view controller…)

So I have a function that shows an alert while Alamofire is doing some stuff and I want to dismiss the alert when Alamofire is done but sometimes it works and sometimes it doesn't! 因此,我有一个函数可以在Alamofire正在执行某些操作时显示警报,并且我想在Alamofire完成后关闭该警报,但有时它可以工作,有时却不起作用! and when it doesn't work I'm getting the error ( iOS 13, Xcode 11 Beta 5 ): Warning: Attempt to dismiss from view controller (UITabBarController: 0x7f90b7013a00) while a presentation or dismiss is in progress! 当它不起作用时,我会收到错误消息( iOS 13,Xcode 11 Beta 5 ): 警告:在演示或关闭过程中,尝试从视图控制器(UITabBarController:0x7f90b7013a00)关闭!

This is the function I use to show the alert: 这是我用来显示警报的功能:

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

Also I'm using tab bars and inside one of the tab bars I'm using the navigation controller and inside that I've a tableview so when the user clicks the cells it goes to another view controller (inside the same storyboard file) using this code: 另外,我在使用选项卡栏,并且在其中一个选项卡栏内使用导航控制器,并且在其中使用表格视图,因此当用户单击单元格时,它将转到使用另一个视图控制器(在同一故事板文件内部)此代码:

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

and then I've also disabled the navigation bar (the header I guess and I'm using a custom button to return to the previews page using this code: 然后我也禁用了导航栏(我猜是标题,并且我使用自定义按钮使用以下代码返回预览页面:

self.navigationController?.popViewController(animated: true)

also here is the Alamofire where I've put the alert function and I'm using it inside viewDidLoad: 这也是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)
                }
            }
        }
    }

This seems like a race condition involving when you call your libHttp(url:) function. 调用libHttp(url :)函数时,这似乎是一种竞争条件。 Check for scenarios where you are dismissing the alert after you pop the viewController from the navigation controller. 从导航控制器中弹出viewController后,请检查是否有解散警报的方案。

Your showLoadingDialog(show : Bool) looks a little strange. 您的showLoadingDialog(show : Bool)看起来有些奇怪。 When passing true to it, to display the alert, everything seems to be setup correctly, but when passing false, to hide the alert, you are creating a new UIAlertController , never actually present it, and then tries to remove it. 当传递true来显示警报时,似乎一切都已正确设置,但是传递false来隐藏警报时,您正在创建一个新的UIAlertController ,从不实际显示它,然后尝试将其删除。 I'm guessing that you really don't want to create a new UIAlertController here, but would instead like to remove an already presented UIAlertController ? 我猜你真的不想在这里创建一个新的UIAlertController ,而是想删除一个已经存在的UIAlertController

Maybe you can do something like this instead? 也许您可以执行类似的操作?

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

Your alert.dismiss call isn't working because you instanciate a new AlertController each time you call the showLoadingDialog . 您的alert.dismiss调用不起作用,因为每次调用showLoadingDialog实例化一个新的showLoadingDialog

Here is a minimum viable working example: 这是一个最小可行的工作示例:

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: 模拟器预览:

模拟器预览

暂无
暂无

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

相关问题 在演示或解雇过程中警告尝试从视图控制器解雇 - warning attempt to dismiss from view controller while a presentation or dismiss is in progress 试图从视图控制器中解雇 - Attempt to dismiss from view controller iOS警告:在进行演示或关闭时尝试从视图控制器中关闭 - iOS Warning: Attempt to dismiss from view controller while a presentation or dismiss is in progress 控制台警告:在进行演示或关闭时尝试从视图控制器中关闭 - Console warning: Attempt to dismiss from view controller while a presentation or dismiss is in progress 警告:尝试从视图控制器中退出 <UINavigationController: 0xb359a20> 在进行演示或解雇时 - Warning: Attempt to dismiss from view controller <UINavigationController: 0xb359a20> while a presentation or dismiss is in progress UISearchController-警告:在进行演示或关闭时尝试从视图控制器关闭 - UISearchController - Warning: Attempt to dismiss from view controller while a presentation or dismiss is in progress 在演示或关闭过程中尝试从视图控制器(UIModalViewController)关闭 - Attempt to dismiss from view controller (UIModalViewController) while a presentation or dismiss is in progress 得到:“在进行演示或解散时尝试从视图控制器中解散” - Getting : “Attempt to dismiss from view controller while a presentation or dismiss is in progress” 在演示或解雇过程中尝试从视图控制器中解除 - Attempt to dismiss from view controller while a presentation or dismiss is in progress iOS 7错误警告:尝试从视图控制器中解除 <UINavigationController: 0x1568db40> 正在进行演示或解雇 - iOS 7 error Warning: Attempt to dismiss from view controller <UINavigationController: 0x1568db40> while a presentation or dismiss is in progress
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM