iOS 引用當前顯示的UIAlertView

來源:互聯網
上載者:User

標籤:alertview

UIAlertView在iOS裡和一般的UIView不一樣,有時候使用起來會有一些不便。特別要引用當前顯示的UIAlertView的時候,就存在一些難度。

UIAlertView在iOS7以前

可以下面的代碼可以解決這個問題:

#pragma mark 尋找當前介面有沒有一個AlertView+(BOOL)isAlert{    for (UIWindow* window in [UIApplication sharedApplication].windows) {        NSArray* subviews = window.subviews;        if ([subviews count] > 0)            if ([[subviews objectAtIndex:0] isKindOfClass:[UIAlertView class]])                return YES;    }    return NO;}#pragma mark 關閉當前介面上的alertView+(void)closeAlert{    for (UIWindow* window in [UIApplication sharedApplication].windows) {        NSArray* subviews = window.subviews;        if ([subviews count] > 0)            if ([[subviews objectAtIndex:0] isKindOfClass:[UIAlertView class]])                [[subviews objectAtIndex:0] dismissWithClickedButtonIndex:0 animated:YES];    }}

可以把它放在一個公用的類中作為靜態方法調用,使用起來非常方便。不幸的是,iOS7以後不能使用了。事實上,在iOS7以後,UIAlertView已經不屬於任何一個window了,-[UIAlertView window]的值一直是nil。 而且alert view 的管理方法在開發文檔裡也沒有列出來。這意味著,即使遍曆整個windows的subviews,也找不到AlertView。

判斷當前keyWindow
/// 尋找當前介面有沒有一個AlertView.+(BOOL)isAlert{    if ([[UIApplication sharedApplication].keyWindow isMemberOfClass:[UIWindow class]])    {        ////There is no alertview present        return  NO;    }    return YES;}

這個方法看起來是比較簡單的,可惜無法引用到UIAlertView,就無法用代碼關閉它。我嘗試用

if ([[UIApplication sharedApplication].keyWindow isMemberOfClass:[UIWindow class]])
{
////There is no alertview present
return ;
}
UIAlertView* alert=(UIAlertView*)[UIApplication sharedApplication].keyWindow;

這樣的代碼,但是失敗了。

國外有提出下面的iOS7處理方案:
Class UIAlertManager = objc_getClass("_UIAlertManager");UIAlertView *topMostAlert = [UIAlertManager performSelector:@selector(topMostAlert)];

我沒有成功運行這個代碼,最重要原因我希望能寫一個公用的方法擷取當前的UIAlertView,所以這個方法我不感興趣。
上面代碼也可以這樣寫:

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

感興趣的同學可以試一下。但據說這個方法Apple Store是不會審核通過的,因為它用到的是未公開的方法。

在當前ViewController定義一個isAlertView變數

這個方法原理比較簡單,但使用起來挺麻煩。

// initialize default flag for alert... If alert is not open set isOpenAlert as NOBOOL isAlertOpen;isAlertOpen = NO;if (isAlertOpen == NO) {    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"Alert is Open" delegate:self cancelButtonTitle:@"Okay!!" otherButtonTitles: nil];    [alert show];    // Now set isAlertOpen to YES    isAlertOpen = YES;}else{    //Do something}
使用Notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(aWindowBecameVisible:) name:UIWindowDidBecomeVisibleNotification object:nil];

然後在aWindowBecameVisible裡驗證:

if ([[theWindow description] hasPrefix:@"<_UIModalItemHostingWin"]){    // This is the alert window}

這個方法也有點麻煩。

在AppDelegate定義公用變數

在AppDelegate.h裡:

@property (nonatomic, assign) BOOL isAlertVisibleOnAppWindow;

在使用UIAlertView的時候:

AppDelegate *delegate = (AppDelegate *) [UIApplication sharedApplication].delegate;if (!delegate.isAlertVisibleOnAppWindow) {    delegate.isAlertVisibleOnAppWindow = YES;    UIAlertView *alertView = [[UIAlertView alloc] init…//alert init code}

在按鈕的點擊事件裡,要給isAlertVisibleOnAppWindow再賦值。

這方法也不容易。

自訂一個MyUIAlertView

使用一個static BOOL alertIsShowing變數,然後override -(void)show selector.
在show的時候,就可以判斷當前alertIsShowing的值。
而且可以自己定義一個close方法。

UIAlertController

蘋果官方文檔介紹,UIAlertView在iOS8以後不贊成再繼續使用,同樣UIAlertViewDelegate可能也要廢棄了。使用UIAlertController來替代UIAlertView。關於UIAlertController的用法我在下一篇博文裡介紹,這裡還是嘗試能否尋找到現有UIAlertController。下面的代碼經測試可以成功運行:

@implementation StringUtils/// 尋找當前介面有沒有一個AlertView.+(BOOL)isAlert{    if ([[UIApplication sharedApplication].keyWindow isMemberOfClass:[UIWindow class]])    {        return  NO;    }    return YES;}/// 關閉當前介面上的alertView.+(void)closeAlert{    UIViewController* c=[self activityViewController];    if([c isKindOfClass:[UIAlertController class]]){        NSLog(@"success");    }    else if([c isKindOfClass:[UINavigationController class]]){        UINavigationController* d =(UINavigationController*)c;        if([d.visibleViewController isKindOfClass:[UIAlertController class]]){            UIAlertController* control=(UIAlertController*)d;            [control dismissViewControllerAnimated:YES completion:^{}];            NSLog(@"success again");        }    }}/// 尋找當前使用中視窗.+ (UIViewController *)activityViewController{    UIViewController* activityViewController = nil;    UIWindow *window = [[UIApplication sharedApplication] keyWindow];    if(window.windowLevel != UIWindowLevelNormal)    {        NSArray *windows = [[UIApplication sharedApplication] windows];        for(UIWindow *tmpWin in windows)        {            if(tmpWin.windowLevel == UIWindowLevelNormal)            {                window = tmpWin;                break;            }        }    }    NSArray *viewsArray = [window subviews];    if([viewsArray count] > 0)    {        UIView *frontView = [viewsArray objectAtIndex:0];        id nextResponder = [frontView nextResponder];        if([nextResponder isKindOfClass:[UIViewController class]])        {            activityViewController = nextResponder;        }        else        {            activityViewController = window.rootViewController;        }    }    return activityViewController;}@end

調用時,使用

[StringUtils closeAlert];

即可關閉當前開啟的UIAlertController視窗。

iOS 引用當前顯示的UIAlertView

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.