標籤: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