iOS - iOS的Window控制(显示/隐藏)

很多情况下,我们需要将其它控件产生的window 隐藏,这几天做项目的时候发现,当自己打开一个带有winodw的控件,然后收到一下抢登消息,自己的app回到了首页,但是这个window还在,因此需要隐藏它。

注意点

  1. UIAlertView 与 UIActionSheet无法从UIApplication.sharedApplication.windows取得。
  2. 既然要隐藏window 级别是Normal的自然不能隐藏。

方案

  1. 为了全局取到 UIAlertView 和 UIActionSheet Hook它们的show方法。或者直接用方法替换的方式,将自定义方法与show方法替换,起到存储的作用。

  2. 做个判断即可。

实现

我这里因为工程里已经集成了Aspects所以就用hook的方式

UIActionSheet

+ (void)load
{
    id sheetShowInViewHook = ^(id aspectInfo) {
        if ([aspectInfo.instance isKindOfClass:[UIActionSheet class]]){
            UIActionSheet *sheet = aspectInfo.instance;
            [UIWindow saveAlertOrSheetView:sheet];
        }
    };
    
    [self aspect_hookSelector:@selector(showInView:)
                  withOptions:AspectPositionAfter
                   usingBlock:sheetShowInViewHook
                        error:nil];
}

UIAlertView

+ (void)load
{
    id alertShowHook = ^(id aspectInfo) {
        if ([aspectInfo.instance isKindOfClass:[UIAlertView class]]){
            UIAlertView *alertView = aspectInfo.instance;
            [UIWindow saveAlertOrSheetView:alertView];
        }
    };
    
    [self aspect_hookSelector:@selector(show)
                  withOptions:AspectPositionAfter
                   usingBlock:alertShowHook
                        error:nil];
}

为了使用方便,就直接给window定一个分类

==这里用NSHashTable 防止重复储存==

static NSHashTable *viewTable;

+ (void)load
{
    viewTable = [NSHashTable weakObjectsHashTable];
}

+ (void)saveAlertOrSheetView:(UIView *)view
{
    [viewTable addObject:view];
}

+ (void)hideAllWindowsExceptNormal
{
    for (UIWindow *window in UIApplication.sharedApplication.windows) {
        BOOL windowLevelNormal = (window.windowLevel != UIWindowLevelNormal);
        if(windowLevelNormal) {
            [window setHidden:YES];
        }
    }
    
    for (UIView *view in viewTable) {
        if ([view isKindOfClass:[UIAlertView class]]) {
            UIAlertView *alertView = view;
            [alertView dismissWithClickedButtonIndex:alertView.cancelButtonIndex animated:NO];
        }
        
        if ([view isKindOfClass:[UIActionSheet class]]) {
            UIActionSheet *acitonSheet = view;
            [acitonSheet dismissWithClickedButtonIndex:acitonSheet.cancelButtonIndex animated:NO];
        }
    }
}

你可能感兴趣的:(iOS - iOS的Window控制(显示/隐藏))