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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了检查UIAlertController是否已经呈现的最佳方法是什么?相关的知识,希望对你有一定的参考价值。

我有一个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)
    

答案

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

换句话说,如果您已将视图控制器告知presentViewController:...,则在呈现的视图控制器被解除之前,您不能再这样做。

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

另一答案

关闭当前控制器并显示警报控制器

 func alert(_ message:String) 
  let alert = UIAlertController(title: "Error!", message: message, preferredStyle: .alert)
  alert.addAction(UIAlertAction(title: "Dismiss", style: .default, handler: nil))
  self.dismiss(animated: false, completion: nil)
  self.present(alert, animated: true,completion: nil)
    
另一答案

如果已经出现警报,您可以在一行中进行测试:

if self.presentedViewController as? UIAlertController != nil 
    print ("alert already presented")

另一答案

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

另一答案

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

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

self.displayAlertController()

另一答案
if ([self.navigationController.visibleViewController isKindOfClass:[UIAlertController class]]) 

      // UIAlertController is presenting.Here


另一答案

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

如果你问你的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")
      
  

另一答案

这是我在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)
    

另一答案

我们可以简单地检查是否有任何视图控制器。

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

    id alert = self.presentedViewController;

    if (alert && [alert isKindOfClass:[UIAlertController class]]) 
      
           *// YES UIAlertController is already presented*
      
    else
       
        // UIAlertController is not presented OR visible.
       
另一答案

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

UIViewController+JCPresentQueue.h

另一答案

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

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

 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)

    
另一答案

对于最新的Swift语言,您可以使用以下内容:

var alert = presentedViewController

if alert != nil && (alert is UIAlertController) 
    // YES UIAlertController is already presented*
 else 
    // UIAlertController is not presented OR visible.

另一答案

Swift 4.2+答案

if UIApplication.topViewController()!.isKind(of: UIAlertController.self)  
            print("UIAlertController is presented")

对于那些不知道如何获得最顶级Viewcontroller的人

extension UIApplication 


public class func topViewController(_ base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? 
    if let nav = base as? UINavigationController 
        return topViewController(nav.visibleViewController)
    
    if let tab = base as? UITabBarController 
        if let selected = tab.selectedViewController 
            return topViewController(selected)
        
    
    if let presented = base?.presentedViewController 
        return topViewController(presented)
    
    return base

以上是关于检查UIAlertController是否已经呈现的最佳方法是什么?的主要内容,如果未能解决你的问题,请参考以下文章

UIAlertController 错误当在 swift 中以模态呈现的视图控制器中调用时

如果已经显示警报,则显示 UIAlertController

如何从 SKScene 呈现 UIAlertController

呈现的 UIViewController 不能呈现 UIAlertController

在呈现的视图控制器上的 UITableViewCell 中呈现 UIAlertController

带有呈现的 UIAlertController 的 UINavigationController 被另外解雇