2011-03-22 11 views
21

दिखाते हुए UIAlertView beforing को खारिज कर देता है मेरे पास एक Utils क्लास है जो कुछ नोटिफिकेशन ट्रिगर होने पर UIAlertView दिखाती है। क्या कोई नया दिखाए जाने से पहले किसी भी खुले यूआईएलर्टव्यू को खारिज करने का कोई तरीका है?आईओएस एक अन्य

currenty मैं जब एप्लिकेशन को पृष्ठभूमि का उपयोग कर

[self checkViews:application.windows]; 
applicationDidEnterBackground

पर

- (void)checkViews:(NSArray *)subviews { 
    Class AVClass = [UIAlertView class]; 
    Class ASClass = [UIActionSheet class]; 
    for (UIView * subview in subviews){ 
     if ([subview isKindOfClass:AVClass]){ 
      [(UIAlertView *)subview dismissWithClickedButtonIndex:[(UIAlertView *)subview cancelButtonIndex] animated:NO]; 
     } else if ([subview isKindOfClass:ASClass]){ 
      [(UIActionSheet *)subview dismissWithClickedButtonIndex:[(UIActionSheet *)subview cancelButtonIndex] animated:NO]; 
     } else { 
      [self checkViews:subview.subviews]; 
     } 
    } 
} 

यह applicationDidEnterBackground पर आसान के रूप में मैं application.windows

कर सकते हैं का उपयोग कर सकते बनाता है में प्रवेश करती है यह कर रहा हूं मैं AppDelegate या सभी विचारों को प्राप्त करने के समान कुछ भी उपयोग करता हूं, उनके माध्यम से लूप करता हूं और किसी भी UIAlertViews को खारिज करता हूं?

उत्तर

28
for (UIWindow* window in [UIApplication sharedApplication].windows) { 
    NSArray* subviews = window.subviews; 
    if ([subviews count] > 0) 
    if ([[subviews objectAtIndex:0] isKindOfClass:[UIAlertView class]]) 
     [(UIAlertView *)[subviews objectAtIndex:0] dismissWithClickedButtonIndex:[(UIAlertView *)[subviews objectAtIndex:0] cancelButtonIndex] animated:NO]; 
} 
+0

वास्तव में अच्छी तरह से काम करता है। धन्यवाद :) –

+2

ऐसा लगता है कि यह आईओएस 6 पर काम नहीं कर रहा है। – erkanyildiz

+3

... और यही कारण है कि निजी आंतरिक दृश्य संरचनाओं को पुन: सक्रिय करना एक नाजुक प्रक्रिया है। –

27

iOS6 संगत संस्करण:

for (UIWindow* w in UIApplication.sharedApplication.windows) 
    for (NSObject* o in w.subviews) 
     if ([o isKindOfClass:UIAlertView.class]) 
      [(UIAlertView*)o dismissWithClickedButtonIndex:[(UIAlertView*)o cancelButtonIndex] animated:YES]; 
+0

यह ठीक है मेरे समय को बचाने के लिए काम करता है ...धन्यवाद – Dhaval

+0

यह स्वीकार्य उत्तर होना चाहिए –

+3

यह एक पुराना सवाल है लेकिन यह आईओएस 7 में काम नहीं कर रहा है। – Moy

1

iOS7 संगत संस्करण:

मैं एक वर्ग अंतरफलक है कि init विधि में सभी उदाहरण संग्रहीत करता है बनाया है।

मुझे पता है कि यह एक बहुत ही अक्षम तरीका है।

#import <objc/runtime.h> 
#import <objc/message.h> 

@interface UIAlertView(EnumView) 

+ (void)startInstanceMonitor; 
+ (void)stopInstanceMonitor; 
+ (void)dismissAll; 
@end 

@implementation UIAlertView(EnumView) 
static BOOL _isInstanceMonitorStarted = NO; 

+ (NSMutableArray *)instances 
{ 
    static NSMutableArray *array = nil; 
    if (array == nil) 
     array = [NSMutableArray array]; 

    return array; 
} 


- (void)_newInit 
{ 
    [[UIAlertView instances] addObject:[NSValue valueWithNonretainedObject:self]]; 
    [self _oldInit]; 
} 

- (void)_oldInit 
{ 
    // dummy method for storing original init IMP. 
} 

- (void)_newDealloc 
{ 
    [[UIAlertView instances] removeObject:[NSValue valueWithNonretainedObject:self]]; 
    [self _oldDealloc]; 

} 
- (void)_oldDealloc 
{ 
    // dummy method for storing original dealloc IMP. 
} 

static void replaceMethod(Class c, SEL old, SEL new) 
{ 
    Method newMethod = class_getInstanceMethod(c, new); 
    class_replaceMethod(c, old, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)); 
} 

+ (void)startInstanceMonitor 
{ 
    if (!_isInstanceMonitorStarted) { 
     _isInstanceMonitorStarted = YES; 
     replaceMethod(UIAlertView.class, @selector(_oldInit), @selector(init)); 
     replaceMethod(UIAlertView.class, @selector(init), @selector(_newInit)); 

     replaceMethod(UIAlertView.class, @selector(_oldDealloc), NSSelectorFromString(@"dealloc")); 
     replaceMethod(UIAlertView.class, NSSelectorFromString(@"dealloc"), @selector(_newDealloc)); 
    } 
} 

+ (void)stopInstanceMonitor 
{ 
    if (_isInstanceMonitorStarted) { 
     _isInstanceMonitorStarted = NO; 
     replaceMethod(UIAlertView.class, @selector(init), @selector(_oldInit)); 
     replaceMethod(UIAlertView.class, NSSelectorFromString(@"dealloc"), @selector(_oldDealloc)); 
    } 
} 

+ (void)dismissAll 
{ 
    for (NSValue *value in [UIAlertView instances]) { 
     UIAlertView *view = [value nonretainedObjectValue]; 

     if ([view isVisible]) { 
      [view dismissWithClickedButtonIndex:view.cancelButtonIndex animated:NO]; 
     } 
    } 
} 
@end 

UIAlertView का उपयोग करने से पहले इंस्टेंस इंस्टेंस प्रारंभ करना।

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    //... 
    //... 

    [UIAlertView startInstanceMonitor]; 

    return YES; 
} 

कॉल अस्वीकार सभी को दिखाने से पहले।

[UIAlertView dismissAll]; 

यदि आप सभी UIAlertViews को नियंत्रित कर सकते हैं तो यह सिंगलटन पैटर्न का उपयोग करना बेहतर है।

लेकिन मेरे मामले में, मुझे UIWebView में जावास्क्रिप्ट अलर्ट संवाद बंद करने के लिए इस कोड की आवश्यकता है।

0

UIAlertView के बाद से UIAlertController के पक्ष (जो एक UIViewController है, रीति से प्रस्तुत) में iOS8 में हटाई गई है, आप 2 अलर्ट एक ही समय में (एक ही ViewController से कम से कम) पूर्व निर्धारित नहीं कर सकते। दूसरी चेतावनी बस प्रस्तुत नहीं की जाएगी।

मैं आंशिक रूप से UIAlertView के व्यवहार का अनुकरण करना चाहता था, साथ ही एक साथ कई अलर्ट दिखाने से रोकना चाहता था। भाई मेरा समाधान है, जो अलर्ट प्रस्तुत करने के लिए विंडो के rootViewController का उपयोग करता है (आमतौर पर, यह ऐपडिलेगेट के नेविगेशन नियंत्रक है)। मैंने इसे ऐपडिलेगेट में घोषित किया, लेकिन आप इसे कहां रख सकते हैं।

यदि आपको इसका उपयोग करने में कोई समस्या आती है, तो कृपया टिप्पणियों में यहां रिपोर्ट करें।

@interface UIViewController (UIAlertController) 

// these are made class methods, just for shorter semantics. In reality, alertControllers 
// will be presented by window's rootViewController (appdelegate.navigationController) 
+ (UIAlertController *)presentAlertWithTitle:(NSString *)title 
            message:(NSString *)message 
          cancelButtonTitle:(NSString *)cancelButtonTitle 
          otherButtonTitles:(NSArray *)otherButtonTitles 
            handler:(void (^)(NSInteger buttonIndex))block; 
+ (UIAlertController *)presentAlertWithTitle:(NSString *)title 
            message:(NSString *)message 
          cancelButtonTitle:(NSString *)cancelButtonTitle; 

@end 

@implementation UIViewController (UIAlertController) 

+ (UIAlertController *)presentAlertWithTitle:(NSString *)title 
            message:(NSString *)message 
          cancelButtonTitle:(NSString *)cancelButtonTitle 
{ 
    return [self presentAlertWithTitle:title message:message cancelButtonTitle:cancelButtonTitle 
        otherButtonTitles:nil handler:nil]; 
} 
+ (UIAlertController *)presentAlertWithTitle:(NSString *)title 
            message:(NSString *)message 
          cancelButtonTitle:(NSString *)cancelButtonTitle 
          otherButtonTitles:(NSArray *)otherButtonTitles 
            handler:(void (^)(NSInteger buttonIndex))block 
{ 
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message 
                  preferredStyle:UIAlertControllerStyleAlert]; 
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { 
     if (block) 
      block(0); 
    }]; 
    [alert addAction:cancelAction]; 
    [otherButtonTitles enumerateObjectsUsingBlock:^(NSString *title, NSUInteger idx, BOOL *stop) { 
     UIAlertAction *action = [UIAlertAction actionWithTitle:title style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { 
      if (block) 
       block(idx + 1); // 0 is cancel 
     }]; 
     [alert addAction:action]; 
    }]; 

    id<UIApplicationDelegate> appDelegate = [[UIApplication sharedApplication] delegate]; 
    UIViewController *rootViewController = appDelegate.window.rootViewController; 
    if (rootViewController.presentedViewController) { 
     [rootViewController dismissViewControllerAnimated:NO completion:^{ 
      [rootViewController presentViewController:alert animated:YES completion:nil]; 
     }]; 
    } else { 
     [rootViewController presentViewController:alert animated:YES completion:nil]; 
    } 
    return alert; 
} 

@end 
संबंधित मुद्दे