UIAlertView在iOS里和一般的UIView不一樣,有時候使用起來會有一些不便箕母。特別要引用當(dāng)前顯示的UIAlertView的時候,就存在一些難度。
在iOS7以前,可以下面的代碼可以解決這個問題
#pragma mark 查找當(dāng)前界面有沒有一個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 關(guān)閉當(dāng)前界面上的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];
}
}
可以把它放在一個公用的類中作為靜態(tài)方法調(diào)用锅移,使用起來非常方便。
不幸的是饱搏,iOS7以后不能使用了非剃。事實(shí)上,在iOS7以后推沸,UIAlertView已經(jīng)不屬于任何一個window了备绽,-[UIAlertView window]的值一直是nil。 而且alert view 的管理方法在開發(fā)文檔里也沒有列出來鬓催。這意味著肺素,即使遍歷整個windows的subviews,也找不到AlertView宇驾。
判斷當(dāng)前keyWindow
/// 查找當(dāng)前界面有沒有一個AlertView.
+(BOOL)isAlert{
if ([[UIApplication sharedApplication].keyWindow isMemberOfClass:[UIWindow class]])
{
////There is no alertview present
return NO;
}
return YES;
}
這個方法看起來是比較簡單的倍靡,可惜無法引用到UIAlertView,就無法用代碼關(guān)閉它课舍。我嘗試用
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)];
我沒有成功運(yùn)行這個代碼,最重要原因我希望能寫一個公用的方法獲取當(dāng)前的UIAlertView雨让,所以這個方法我不感興趣雇盖。
上面代碼也可以這樣寫:
UIAlertView *topMostAlert = [NSClassFromString(@"_UIAlertManager") performSelector:@selector(topMostAlert)];
感興趣的同學(xué)可以試一下。但據(jù)說這個方法Apple Store是不會審核通過的栖忠,因?yàn)樗玫降氖俏垂_的方法崔挖。
在當(dāng)前ViewController定義一個isAlertView變量
這個方法原理比較簡單,但使用起來挺麻煩庵寞。
// initialize default flag for alert... If alert is not open set isOpenAlert as NO
BOOL 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里驗(yàn)證:
if ([[theWindow description] hasPrefix:@"<_UIModalItemHostingWin"])
{
// This is the alert window
}
這個方法也有點(diǎn)麻煩狸相。
在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
}
在按鈕的點(diǎn)擊事件里,要給isAlertVisibleOnAppWindow再賦值捐川。
這方法也不容易脓鹃。
自定義一個MyUIAlertView
使用一個static BOOL alertIsShowing變量,然后override -(void)show selector.
在show的時候古沥,就可以判斷當(dāng)前alertIsShowing的值瘸右。
而且可以自己定義一個close方法。
UIAlertController
蘋果官方文檔介紹岩齿,UIAlertView在iOS8以后不贊成再繼續(xù)使用太颤,同樣UIAlertViewDelegate可能也要廢棄了。使用UIAlertController來替代UIAlertView盹沈。關(guān)于UIAlertController的用法我在下一篇博文里介紹龄章,這里還是嘗試能否查找到現(xiàn)有UIAlertController。下面的代碼經(jīng)測試可以成功運(yùn)行:
@implementation StringUtils
/// 查找當(dāng)前界面有沒有一個AlertView.
+(BOOL)isAlert{
if ([[UIApplication sharedApplication].keyWindow isMemberOfClass:[UIWindow class]])
{
return NO;
}
return YES;
}
/// 關(guān)閉當(dāng)前界面上的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");
}
}
}
/// 查找當(dāng)前活動窗口.
+ (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
調(diào)用時乞封,使用
[StringUtils closeAlert];
即可關(guān)閉當(dāng)前打開的UIAlertController窗口做裙。