What is the best way to check if a UIAlertController is already presenting?

后端 未结 13 2058
后悔当初
后悔当初 2020-12-04 17:26

I have a tableview which, when loaded, each cell could possibly return an NSError, which I have chosen to display in a UIAlertController. Problem is I get this error in the

相关标签:
13条回答
  • 2020-12-04 17:52

    For latest Swift language you can use following:

    var alert = presentedViewController
    
    if alert != nil && (alert is UIAlertController) {
        // YES UIAlertController is already presented*
    } else {
        // UIAlertController is not presented OR visible.
    }
    
    0 讨论(0)
  • 2020-12-04 17:53
    if ([self.navigationController.visibleViewController isKindOfClass:[UIAlertController class]]) {
    
          // UIAlertController is presenting.Here
    
    }
    
    0 讨论(0)
  • 2020-12-04 17:58

    I found I needed to create a queue to stack the UIAlertController requests.

    NSMutableArray *errorMessagesToShow; // in @interface
    errorMessagesToShow=[[NSMutableArray alloc] init];  // in init
    
    -(void)showError:(NSString *)theErrorMessage{
        if(theErrorMessage.length>0){
            [errorMessagesToShow addObject:theErrorMessage];
            [self showError1];
        }
    }
    -(void)showError1{
        NSString *theErrorMessage;
        if([errorMessagesToShow count]==0)return; // queue finished
    
        UIViewController* parentController =[[UIApplication sharedApplication]keyWindow].rootViewController;
        while( parentController.presentedViewController &&
          parentController != parentController.presentedViewController ){
            parentController = parentController.presentedViewController;
        }
        if([parentController isKindOfClass:[UIAlertController class]])return;  // busy
    
        // construct the alert using [errorMessagesToShow objectAtIndex:0]
        //  add to each UIAlertAction completionHandler [self showError1];
        //   then
    
        [errorMessagesToShow removeObjectAtIndex:0];
        [parentController presentViewController:alert animated:YES completion:nil]; 
    }
    
    0 讨论(0)
  • 2020-12-04 18:01

    Swift 4.2+ Answer

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

    For those who don't know how to get top most 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
    }}
    

    Swift 5+ Answer 'keyWindow' was deprecated in iOS 13.0 suggested edit

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

    For those who don't know how to get top most Viewcontroller

    extension UIApplication {
    
    
    public class func topViewController(_ base: UIViewController? = UIApplication.shared.windows.first?.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
    }}
    
    0 讨论(0)
  • 2020-12-04 18:03

    It is not the UIAlertController that is "already presenting", it is MessagesMasterVC. A view controller can only present one other view controller at a time. Hence the error message.

    In other words, if you have told a view controller to presentViewController:..., you cannot do that again until the presented view controller has been dismissed.

    You can ask the MessagesMasterVC whether it is already presenting a view controller by examining its presentedViewController. If not nil, do not tell it to presentViewController:... - it is already presenting a view controller.

    0 讨论(0)
  • 2020-12-04 18:03

    I used that to detect and remove and alert.

    First we create an alert with following function.

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

    And in some other part of your code

        if yourAlert != nil {
    
          yourAlert.dismiss(animated: true, completion: nil)
    
        }
    
    0 讨论(0)
提交回复
热议问题