10

In my iOS application, I have a timer firing up, and when it fires, I need to be able to detect whether there's an Alert (UIAlertView) or an Action Sheet (UIActionSheet) open.

One way would be to modify the code presenting the alerts/actionsheets - but unfortunately this is not an option in my case.

So, the question is - is there a way of knowing/detecting whether an alert or action sheet have been opened?

Is there any notifications sent upon opening, or any traversal of the view hierarchy to detect it?

Thanks

Andy Obusek
  • 12,614
  • 4
  • 41
  • 62
Reuven
  • 2,142
  • 3
  • 18
  • 30

6 Answers6

17

They do send an alert when they open, but only to their delegate -- Check this question for a nice approach to that problem. Techzen recommends setting a boolean flag to YES when you open up the alert, and setting it back to NO when you dismiss the alert.

EDIT:

Since you don't have access at all to the code, why not try this clunky piece of code:

-(BOOL) doesAlertViewExist {
  for (UIWindow* window in [UIApplication sharedApplication].windows) {
    NSArray* subviews = window.subviews;
    if ([subviews count] > 0) {

      BOOL alert = [[subviews objectAtIndex:0] isKindOfClass:[UIAlertView class]];
      BOOL action = [[subviews objectAtIndex:0] isKindOfClass:[UIActionSheet class]];

      if (alert || action)
        return YES;
     }
  }
  return NO;
}
Community
  • 1
  • 1
Sam Ritchie
  • 10,988
  • 4
  • 42
  • 53
  • 2
    THANKS! I had to apply two changes to the proposal: (1) subviews in an NSArray* and not UIView*. (2) Seems like the UIActionSheet is not the first [0] subview, but the second [1]. So I iterated the view hierarchy... Code is posted as answer... – Reuven Dec 06 '10 at 06:15
  • I used TechZen's other suggestion of retaining a reference. I found this worked very elegantly. – Keith at Ideal Films Feb 21 '12 at 15:29
12
- (BOOL) doesAlertViewExist {
    for (UIWindow* window in [UIApplication sharedApplication].windows) {
        for (UIView* view in window.subviews) {
            BOOL alert = [view isKindOfClass:[UIAlertView class]];
            BOOL action = [view isKindOfClass:[UIActionSheet class]];
            if (alert || action)
                return YES;
        }
    }
    return NO;
}
Reuven
  • 2,142
  • 3
  • 18
  • 30
  • hello i am also facing same problem i tried with the above code however when i try to print the array of "window.subviews" , not getting any object of uiactionsheet .Before this i kept open one actionsheet .what can be the problem please give some solution on this – user968597 Jun 08 '12 at 08:41
  • I've only used this code on an iPhone - can it be you're using it on an iPad? – Reuven Jun 10 '12 at 14:44
  • Not Working at all on ipad. :( – Tarun Mar 01 '13 at 10:55
2

Detecting alerts seems relatively easy, but action sheets had me stumped. In iOS 6.1 I had to go one step further

BOOL IsActionOpen(UIView* aView) {
BOOL    actionOpen = NO;
if (aView) {
    if ([aView isKindOfClass:[UIActionSheet class]]) {
        actionOpen = YES;
    }
    else if (aView.subviews.count > 0) {
        for (UIView* aSubview in aView.subviews) {
            if ( IsActionOpen( aSubview)) {
                actionOpen = YES;
                break;
            }
        }
    }
}
return actionOpen;

}

- (BOOL) isAnActionSheetOpen {
BOOL    actionOpen = NO;
for (UIWindow* w in [UIApplication sharedApplication].windows) {
    actionOpen =  IsActionOpen(w);
    if (actionOpen)
        break;
}
return actionOpen;

}

user2002649
  • 710
  • 5
  • 9
  • In iOS 7 this code works for action sheets, but it no longer works for alert views. Seems like the best solution for alert views is to keep track of them... http://stackoverflow.com/q/18702565/268153 – Jeff Mascia Nov 18 '13 at 23:31
2

You can also check for the view's window property:

if(actionSheet.window)
    isBeingPresented = YES;
Peter DeWeese
  • 18,141
  • 8
  • 79
  • 101
1

thanx for the help, but since iOS 6, the code piece doesn't work anymore. However, I fixed the issue with this code. Hope this helps

for (UIWindow* window in [UIApplication sharedApplication].windows) {
    NSArray* subviews = window.subviews;
    if ([subviews count] > 1) {
        BOOL alert = [[subviews objectAtIndex:1] isKindOfClass:[UIAlertView class]];
        BOOL action = [[subviews objectAtIndex:1] isKindOfClass:[UIActionSheet class]];

        if (alert || action)
            return YES;
    }
}
return NO;
SlumTheSlug
  • 115
  • 13
1
-(BOOL)GetKeyWindow {    
        UIViewController *presentedViewController = myAppDelegate.window.rootViewController.presentedViewController;

        if (presentedViewController) {

            if ([presentedViewController isKindOfClass:[UIActivityViewController class]] || [presentedViewController isKindOfClass:[UIAlertController class]]) {        

                return YES;
            }else{
                return NO;
                NSLog(@"not present");
            }   
        }
        else{
            return NO;
        } 
}
Akshay Sunderwani
  • 12,428
  • 8
  • 29
  • 52