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]
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
Change the Root View of Uihostingcontroller in Swiftui
How to Draw a Point Using Core Graphics
How to Disable 4 Finger Gestures on iPad
Fix Cordova Geolocation Ask for Location Message
How to Install an Unsigned IPA File on My Device Using an Apple Developer Account
Add Modal Popup to Map Annotation - Swift 3.0
Completion Block for Popviewcontroller
iOS Change Navigation Bar Title Font and Color
How to Do Weak Linking in Swift
How to Change Status Bar Style - iOS 12
Perform a Deeplink from Swiftui Widget on Tap
How to Disable iPhone 6 Native Resolution
Mfmailcomposeviewcontroller Crashes Because of Global Appearance Properties on iOS6
How to Send Data from iPhone to Apple Watch in Os2 in Objective-C
Removing Duplicate Objects from Fetch Based on Object Parameter Updated Swift