【问题标题】:How to dismiss uialertcontroller from view completely?如何从视图中完全消除 uialertcontroller?
【发布时间】:2015-06-17 07:24:38
【问题描述】:

实际上,我有一个具有 4 种方法的视图控制器。 3 种方法用于显示UIAlertController,没有“确定”或“取消”等操作按钮。仅标题和消息。解雇那些UIAlertController 的最终方法。我的警报之一是在请求异步调用时显示。当我们得到结果时,它会关闭并隐藏。

问题是当我的第一个警报正在显示时突然连接丢失,而另一个将显示“Internet Lost”消息的警报由于该警告而无法显示。

2015-06-17 13:49:04.787 myauction[2404:40506] Warning: Attempt to present <UIAlertController: 0x7f8d136bafa0> on <myauction.AuctionLatestViewController: 0x7f8d13771180> while a presentation is in progress!

这意味着我无法成功解除第一个警报。有什么帮助吗?

这是我的警报控制器

import UIKit

class MyAlertViewController:UIViewController{

var myAlertController : UIAlertController!

func displayLoadingAlert(viewController: UIViewController?) -> UIAlertController {

    var controllerToPresent = viewController
    if controllerToPresent == nil {
        controllerToPresent = self
    }

    //create an alert controller
    myAlertController = UIAlertController(title: "Loading...", message: "We are getting the data,Please Wait", preferredStyle: .Alert)

    let indicator = UIActivityIndicatorView()
    indicator.color = UIColor.redColor()
    indicator.setTranslatesAutoresizingMaskIntoConstraints(false)
    myAlertController.view.addSubview(indicator)

    let views = ["pending" : myAlertController.view, "indicator" : indicator]
    var constraints = NSLayoutConstraint.constraintsWithVisualFormat("V:[indicator]-(7)-|", options: nil, metrics: nil, views: views)
    constraints += NSLayoutConstraint.constraintsWithVisualFormat("H:|[indicator]|", options: nil, metrics: nil, views: views)
    myAlertController.view.addConstraints(constraints)

    indicator.userInteractionEnabled = false
    indicator.startAnimating()

    controllerToPresent!.presentViewController(myAlertController, animated: true, completion: nil)

    return myAlertController
}

func connectionErrorAlert(viewController: UIViewController?) -> UIAlertController {

    var controllerToPresent = viewController
    if controllerToPresent == nil {
        controllerToPresent = self
    }

    //create an alert controller
    myAlertController = UIAlertController(title: "Not Connected", message: "No Internet Connection", preferredStyle: .Alert)
    let defaultAction = UIAlertAction(title: "OK", style: .Default,handler:nil)
    myAlertController.addAction(defaultAction)

    controllerToPresent!.presentViewController(myAlertController, animated: true, completion: nil)

    return myAlertController
}

func requestTimeOutErrorAlert(viewController: UIViewController?) -> UIAlertController {

    var controllerToPresent = viewController
    if controllerToPresent == nil {
        controllerToPresent = self
    }

    //create an alert controller
    myAlertController = UIAlertController(title: "Request Time Out", message: "Please Tap Retry to Get The Data", preferredStyle: .Alert)
    let defaultAction = UIAlertAction(title: "OK", style: .Default,handler:nil)
    myAlertController.addAction(defaultAction)

    controllerToPresent!.presentViewController(myAlertController, animated: true, completion: nil)

    return colayAlertController
}

func dismissLoadingAlert(){
    myAlertController.dismissViewControllerAnimated(true, completion: nil)
}

}

这是我的视图控制器(注意我不会显示 myAlertViewController 的初始化)

func getResults{
     api.searchCar()
     //This is where i start to load my first alert every time it call
     self.myAlertViewController = displayLoadingAlert(self)
}

func didReceiveAPIResults(results: NSDictionary,headers:JSON) {
     dispatch_async(dispatch_get_main_queue(), {
          //do about showing the results....

          //Then i dismiss my first loading alert
          self.myAlertController.dismissViewControllerAnimated(true){}
     })
}

func didNotReceiveAPIResults(results: Bool,error:NSError){
    dispatch_async(dispatch_get_main_queue(), {
        //I did dismiss the first alert before i gonna show another one
        self.myAlertController.dismissViewControllerAnimated(true){
        if (results) {
            if error.localizedDescription == "The Internet connection appears to be offline."{
                self.myAlertViewController = connectionErrorAlert(self)
                self.carTableView.hidden=true
                self.retryButton?.hidden=false
                self.retryButton?.enabled=true
            }
            if error.localizedDescription == "Request Time Out."{
                self.myAlertViewController = requestTimeOutErrorAlert(self)
                self.carTableView.hidden=true
                self.retryButton?.hidden=false
                self.retryButton?.enabled=true
            }

        }else{
            //self.myAlertController.displayLoadingAlert(self)
            self.retryButton?.hidden=true
            self.retryButton?.enabled=false
            self.carTableView.hidden=false
            self.carTableView.reloadData()
        }
      }
    })
}

【问题讨论】:

    标签: ios swift uialertcontroller


    【解决方案1】:

    您应该在dismissViewControllerAnimated方法的completion块中插入您的代码,然后再以模态方式呈现另一个ViewController

    看看你的代码,我已经更新了:

    func didNotReceiveAPIResults(results: Bool,error:NSError){
        dispatch_async(dispatch_get_main_queue(), {
            //
            // I'm calling your error message in the completion block of the
            // dismissViewControllerAnimated Method
            //
            self.myAlertController.dismissViewControllerAnimated(true) {
            if (results) {
                if error.localizedDescription == "The Internet connection appears to be offline."{
                    self.myAlertController.connectionErrorAlert(self)
                }
    
                if error.localizedDescription == "Request Time Out."{
                    self.myAlertController.requestTimeOutErrorAlert(self)
                }
    
                //
                // Moved this code out of your if-statements since they are called
                // no matter which case is true
                //
                self.carTableView.hidden=true
                self.retryButton?.hidden=false
                self.retryButton?.enabled=true
            } else {
                //self.myAlertController.displayLoadingAlert(self)
                self.retryButton?.hidden=true
                self.retryButton?.enabled=false
                self.carTableView.hidden=false
                self.carTableView.reloadData()
            }
            }
        })
    }
    

    【讨论】:

    • 我收到了错误,您介意再检查一下吗?谢谢
    • 对不起。错误的右括号。现在检查行尾。
    • 第一个警报“正在加载”不会关闭,即使我要显示另一个警报。我是否也需要更改该 funcdismissLoadingAlert() 吗?如果您需要 myalertController 方法,我可以提供你。
    • 你是从哪个class 打电话给你的func didNotReceiveAPIResults
    • 我的主视图将显示多个数据。didReceiveAPIResults() 和 didNotReceiveAPIResults() 来自协议内部的我的 api。请看一下:puu.sh/is23l/2764113ed9.png。我还更新了我的代码,让你看得更清楚
    【解决方案2】:

    首先,我犯了一个错误,因为我正在为警报创建新的视图控制器而不是定义扩展名。所以,如果一些正在搜索结果的初学者,不要像我上面的代码一样。所以这是答案。

    如果您想添加自定义警报,请使用这样的扩展。

    import UIKit
    
    extension UIAlertController {
    
    class func displayLoadingAlert() -> UIAlertController {
    
        //create an alert controller
        let myAlertController = UIAlertController(title: "Loading...", message: "We are getting the data,Please Wait...", preferredStyle: .Alert)
    
        let indicator = UIActivityIndicatorView()
        indicator.color = UIColor.redColor()
        indicator.setTranslatesAutoresizingMaskIntoConstraints(false)
        myAlertController.view.addSubview(indicator)
    
        let views = ["pending" : myAlertController.view, "indicator" : indicator]
        var constraints = NSLayoutConstraint.constraintsWithVisualFormat("V:[indicator]-(7)-|", options: nil, metrics: nil, views: views)
        constraints += NSLayoutConstraint.constraintsWithVisualFormat("H:|[indicator]|", options: nil, metrics: nil, views: views)
        myAlertController.view.addConstraints(constraints)
    
        indicator.userInteractionEnabled = false
        indicator.startAnimating()
    
        return myAlertController
    }
    
    class func connectionErrorAlert() -> UIAlertController {
    
        let myAlertController = UIAlertController(title: "Not Connected", message: "No Internet Connection", preferredStyle: .Alert)
        let defaultAction = UIAlertAction(title: "OK", style: .Default,handler:nil)
        myAlertController.addAction(defaultAction)
        return myAlertController
    }
    
    class func requestTimeOutErrorAlert() -> UIAlertController {
        // same as above
    }
    }
    

    那么如何从其他视图控制器中使用它(用于显示和关闭)

    class ViewController : UIViewController{
    
           var myAlert : UIAlertController!
           //For displaying the one of the alert
           func getResults(){
                myAlert = UIAlertController.displayLoadingAlert()
                self.presentViewController(myAlert, animated: true, completion: nil)
           }
           //For dismissing the alert,please add the code in the completion that will do after dismiss
          func afterGettingResults(){
               self.myAlert.dismissViewControllerAnimated(true){
                   //do your job after dismiss is done
               }
          }
    } 
    

    希望对大家有所帮助。感谢@ezCoding,它试​​图帮助我摆脱我的这个黑暗错误,让我走向成功。

    【讨论】:

      猜你喜欢
      • 2014-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      • 2017-03-07
      • 2014-01-09
      相关资源
      最近更新 更多