首页 文章

检查UIAlertController是否已经呈现的最佳方法是什么?

提问于
浏览
87

我有一个tableview,当加载时,每个单元格可能会返回一个NSError,我已经选择在UIAlertController中显示它 . 问题是如果返回多个错误,我会在控制台中收到此错误 .

警告:尝试在MessagesMasterVC上呈现UIAlertController:0x14e64cb00:0x14e53d800已经呈现(null)

理想情况下,我希望在我的UIAlertController扩展方法中处理这个问题 .

class func simpleAlertWithMessage(message: String!) -> UIAlertController {

    let alertController = UIAlertController(title: nil, message: message, preferredStyle: UIAlertControllerStyle.Alert)
    let cancel = UIAlertAction(title: "Ok", style: .Cancel, handler: nil)

    alertController.addAction(cancel)
    return alertController
}

基于matt的答案,我将扩展名更改为UIViewController扩展,更加清晰,并节省了大量的presentViewController代码 .

func showSimpleAlertWithMessage(message: String!) {

    let alertController = UIAlertController(title: nil, message: message, preferredStyle: UIAlertControllerStyle.Alert)
    let cancel = UIAlertAction(title: "Ok", style: .Cancel, handler: nil)

    alertController.addAction(cancel)

    if self.presentedViewController == nil {
        self.presentViewController(alertController, animated: true, completion: nil)
    }
}

9 回答

  • 94

    此类别可以自动管理UIAlertController的所有模态控制器 .

    UIViewController+JCPresentQueue.h

  • -2

    我们可以简单地检查是否有任何视图 .

    如果出现,然后检查它是否是一种UIAlertController .

    id alert = self.presentedViewController;
    
        if (alert && [alert isKindOfClass:[UIAlertController class]]) 
          {
               *// YES UIAlertController is already presented*
          }
        else
           {
            // UIAlertController is not presented OR visible.
           }
    
  • 2

    UIAlertController不是“已经呈现”,而是MessagesMasterVC . 视图控制器一次只能呈现一个其他视图控制器 . 因此错误消息 .

    换句话说,如果您已将视图控制器告知 presentViewController:... ,则在呈现的视图控制器被解除之前,您无法再次执行此操作 .

    你可以通过检查它的 presentedViewController 来询问MessagesMasterVC它是否已经呈现了一个视图控制器 . 如果不是 nil ,请不要告诉 presentViewController:... - 它已经呈现了一个视图控制器 .

  • 0
    if ([self.navigationController.visibleViewController isKindOfClass:[UIAlertController class]]) {
    
          // UIAlertController is presenting.Here
    
    }
    
  • -1

    那么,从我的观点来看,上面建议的解决方案存在一个基本问题:

    如果你问你的ViewController,属性'presentViewController'是否为nil且答案是假的,你不能得出结论,你的UIAlertController已经出现了 . 它可以是任何呈现的ViewController,例如一个popOver . 所以我的建议是肯定检查,警报是否已经在屏幕上是如下(将presentViewController转换为UIAlertController):

    if self.presentedViewController == nil {
       // do your presentation of the UIAlertController
       // ...
    } else {
       // either the Alert is already presented, or any other view controller
       // is active (e.g. a PopOver)
       // ...
    
       let thePresentedVC : UIViewController? = self.presentedViewController as UIViewController?
    
       if thePresentedVC != nil {
          if let thePresentedVCAsAlertController : UIAlertController = thePresentedVC as? UIAlertController {
             // nothing to do , AlertController already active
             // ...
             print("Alert not necessary, already on the screen !")
    
          } else {
             // there is another ViewController presented
             // but it is not an UIAlertController, so do 
             // your UIAlertController-Presentation with 
             // this (presented) ViewController
             // ...
             thePresentedVC!.presentViewController(...)
    
             print("Alert comes up via another presented VC, e.g. a PopOver")
          }
      }
    

    }

  • 27

    这是我在Swift 3中使用的解决方案 . 它是一个向用户显示警报的功能,如果在用户解除警报之前多次调用它,它会将新的警报文本添加到已经呈现的警报中 . 如果正在显示其他视图,则不会显示警报 . 并非所有人都同意这种行为,但它适用于简单的情况 .

    extension UIViewController {
        func showAlert(_ msg: String, title: String = "") {
            if let currentAlert = self.presentedViewController as? UIAlertController {
                currentAlert.message = (currentAlert.message ?? "") + "\n\nUpdate:\(title): \(msg)"
                return
            }
    
            // create the alert
            let alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
    
            // show the alert
            self.present(alert, animated: true, completion: nil)
        }
    }
    
  • 8

    我用它来检测,删除和警报 .

    首先,我们使用以下功能创建警报 .

    var yourAlert :UIAlertController!
    
     func useYouAlert (header: String, info:String){
    
    
        yourAlert = UIAlertController(title:header as String, message: info as String, preferredStyle: UIAlertControllerStyle.alert)
    
    
    
        let okAction = UIAlertAction(title: self.langText[62]as String, style: UIAlertActionStyle.default) { (result : UIAlertAction) -> Void in
            print("OK") 
    
        }
    
    
        yourAlert.addAction(okAction)
        self.present(yourAlert.addAction, animated: true, completion: nil)
    
    }
    

    在代码的其他部分

    if yourAlert != nil {
    
          yourAlert.dismiss(animated: true, completion: nil)
    
        }
    
  • 0

    当我试图在 Main Thread 之外的其他线程中处理 UI elements 时,这发生在我身上 . 当我在过滤器数组块中显示警报时,我遇到了同样的问题 . 当我将警报演示器从过滤器块中取出时,来自控制台的警告消失了 .

  • 0

    只需关闭当前的控制器并出示您想要的控制器,即

    self.dismiss(animated: false, completion: nil)

    self.displayAlertController()

相关问题