Skip to content

Instantly share code, notes, and snippets.

@ripperhe
Last active September 18, 2018 06:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ripperhe/1a71650c9eef374d5db9b4ba311e1b6d to your computer and use it in GitHub Desktop.
Save ripperhe/1a71650c9eef374d5db9b4ba311e1b6d to your computer and use it in GitHub Desktop.
在不调用私有 api 的情况下,如何禁止一个一个 window 变成 keyWindow,以下是一种方案
#import <UIKit/UIKit.h>
@interface ZYSuspensionContainer : UIWindow
@property (nonatomic, weak) UIWindow *oldOldKeyWindow;
@property (nonatomic, weak) UIWindow *oldKeyWindow;
@end
#import "ZYSuspensionContainer.h"
@implementation ZYSuspensionContainer
- (void)makeKeyWindow
{
// 记录当前的 keyWindow
if (self.oldKeyWindow) {
self.oldOldKeyWindow = self.oldKeyWindow;
}else{
self.oldOldKeyWindow = nil;
}
self.oldKeyWindow = [UIApplication sharedApplication].keyWindow;
[super makeKeyWindow];
}
- (void)becomeKeyWindow
{
[super becomeKeyWindow];
/**
1. makeKeyAndVisible 方法会调用 makeKeyWindow
2. keyWindow hidden=YES 的时候,会找 windows 最后一个 window,设置为 keyWindow,所以也会调用 makeKeyWindow
makeKeyWindow 内部会调用 becomeKeyWindow;调用父类 makeKeyWindow 之前,self 还没有变成 keyWindow
becomeKeyWindow 调用的时候,self 已经变成了 keyWindow
*/
if (!self.oldKeyWindow) {
// oldKeyWindow 都没有,那我是第一个 window,也是唯一一个 window,直接返回
return;
}
if ([self.oldKeyWindow isKindOfClass:[self class]]) {
// 从 self 这种类型过来,那不处理了,应该所有 window 都是这种类型
return;
}
if (self.oldOldKeyWindow == self.oldKeyWindow) {
// 这家伙反复设置 keyWindow 给 self,以免循环设置,直接将 keyWindow 设置给 appdelegate window
[[UIApplication sharedApplication].delegate.window makeKeyWindow];
return;
}
if (self.oldKeyWindow.isHidden == NO) {
// 原来的 keyWindow 没有隐藏,并且不是 self 这种类型,直接将 keyWindow 设置回它
[self.oldKeyWindow makeKeyWindow];
return;
}
// self.oldKeyWindow.isHidden == YES 这家伙隐藏了,那看来我得找一个除开它之外的合适的 window
UIWindow *targetWindow = nil;
NSArray <UIWindow *>*windows = [UIApplication sharedApplication].windows;
for (UIWindow *window in windows.reverseObjectEnumerator) {
if ([window isKindOfClass:[self class]]) {
// 本类型 跳过
continue;
}
if (window.hidden == YES || window.opaque == NO) {
// 隐藏的 或者 透明的 跳过
continue;
}
if (CGRectEqualToRect(window.bounds, [UIScreen mainScreen].bounds) == NO) {
// 不是全屏的 跳过
continue;
}
targetWindow = window;
break;
}
if (targetWindow) {
[targetWindow makeKeyWindow];
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment