Find Uialertview Without Having Reference to It iOS 7

Find UIAlertView without having reference to it iOS 7

In iOS7, the UIAlertView window does not appear in -[UIApplication windows]. In fact, the UIAlertView itself is never added to any window, -[UIAlertView window] is always nil. Instead, the alert view manages a variety of undocumented views placed in -[UIApplication keyWindow] with no reference back to the alert view.

Your only real option in iOS7 is to actually keep track of your alert views.

Find UIAlertView without having reference to it

[UPDATE] Actually the solution below is not working for iOS 7, because the alert views are not bound to a specific window any more. Read here for details: https://stackoverflow.com/a/18703524/942107

Based on KennyTM'm advice in another question Sebastien provided link to, I've created a UIAlertView category with a method returning the UIAlertView if shown to be able to dismiss it programatically.

UIAlertViewAdditions.h:

#import <UIKit/UIKit.h>

@interface UIAlertView (UIAlertViewAdditions)

+ (UIAlertView *) getUIAlertViewIfShown;

@end

UIAlertViewAdditions.m:

#import "UIAlertViewAdditions.h"

@implementation UIAlertView (UIAlertViewAdditions)

+ (UIAlertView *) getUIAlertViewIfShown {
if ([[[UIApplication sharedApplication] windows] count] == 1) {
return nil;
}

UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
if ([window.subviews count] > 0) {
UIView *view = [window.subviews objectAtIndex:0];
if ([view isKindOfClass:[UIAlertView class]]) {
return (UIAlertView *) view;
}
}
return nil;
}

@end

Dismissing a UIAlertView in ios 7 not working?

Rather than using your O(n^2) approach to close the alert, it would probably be more lightweight (and iOS 7 valid) to create private properties for your alerts and reference and dismiss them via their synthesized getters. Also, I have from time to time set a tag on the alertview and referenced it via its tag as a quick and dirty solution.

If either of these solutions are too simple for the context of your application I might suggest rethinking your use of alertviews. Too many apps abuse alertviews and in my opinion they should be used very sparingly - just to add some unsolicited feedback :).

A different approach that could help you is to implement a block-based callback upon completion of the alertview's life. See Simplify UIAlertView with Blocks.

Check if a UIAlertView is showing

On the object that calls set an ivar before invoking the show method on your UIAlertView.

...

if (!self.alertShowing) {
theAlert = [[UIAlertView alloc] initWithTitle:title message:details delegate:self cancelButtonTitle:nil otherButtonTitles:@"Okay", nil];
self.alertShowing = YES;
[theAlert show];
}

...

Then in your delegate method for the alert manage setting your flag ivar to no:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
...
self.alertShowing = NO;
}

If you want the alerts to show sequentially, I would post notifications to add each message to a queue and then only take a message off the queue after an alert is dismissed.

How to add subview inside UIAlertView for iOS 7?

You can really change accessoryView to customContentView in iOS7 (and it seems that in iOS8 as well) UIAlertView

[alertView setValue:customContentView forKey:@"accessoryView"];

Try this code:

UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"TEST" message:@"subview" delegate:nil cancelButtonTitle:@"NO" otherButtonTitles:@"YES", nil];
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 80, 40)];
[av setValue:v forKey:@"accessoryView"];
v.backgroundColor = [UIColor yellowColor];
[av show];

Remember that you need set custom accessoryView before the call [alertView show]

enter image description here

iPhone: detecting if a UIAlert/UIActionSheet are open

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

Can i check if any UIAlertView displaying right now?

For devices less than iOS 7 :-

When you make the body of the UIAlertView , the [alertView Show] adds a subview on the main window. So to detect the UIAlertView you simply have to check for the subviews of the current UIView as UIAlertView inherits from UIView.

for (UIWindow* window in [UIApplication sharedApplication].windows){
for (UIView *subView in [window subviews]){
if ([subView isKindOfClass:[UIAlertView class]]) {
NSLog(@"AlertView is Present");
}else {
NSLog(@"AlertView Not Available");
}
}
}

EDIT:- For devices using iOS 7

Class UIAlertManager = objc_getClass("_UIAlertManager");
UIAlertView *Alert = [UIAlertManager performSelector:@selector(Alert)];

and

UIAlertView *Alert = [NSClassFromString(@"_UIAlertManager") performSelector:@selector(Alert)];

NOTE :- If you cannot use third party API's then your only real option in iOS7 is to actually keep track of your alert views.



Related Topics



Leave a reply



Submit