如何在所有视图顶层添加UIViewController,不受UIWindow根控制器变更影响?
稳定在顶层显示UIViewController的最优方案
方案一:自定义高优先级UIWindow
这是最可靠的方案,核心是给自定义窗口设置高于普通窗口的层级,彻底脱离主window的rootViewController变更影响:
- 创建独立UIWindow,设置更大的
windowLevel(比如UIWindowLevelAlert + 1,确保比系统弹窗层级还高) - 将目标控制器设为该window的rootViewController
- 显示窗口即可,无需依赖主window的状态
代码示例(Objective-C):
// 建议用全局或强引用持有该window,避免被释放 @property (nonatomic, strong) UIWindow *topLevelWindow; // 创建并显示顶层控制器 - (void)showTopLevelVC { self.topLevelWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; // 设置窗口级别,确保在所有普通窗口之上 self.topLevelWindow.windowLevel = UIWindowLevelAlert + 1; // 初始化目标控制器 YourTargetViewController *targetVC = [[YourTargetViewController alloc] init]; self.topLevelWindow.rootViewController = targetVC; // 显示窗口 self.topLevelWindow.hidden = NO; // 如果需要让该窗口接收触摸事件,执行下面一行(可选) // [self.topLevelWindow makeKeyAndVisible]; }
方案二:直接将控制器视图添加到顶层窗口
如果不想额外创建window,可以直接把目标控制器的view添加到当前最顶层的window上,同样能避免主window的root变更影响:
- 获取当前活跃场景的顶层窗口(iOS13+需适配多场景)
- 将控制器的view添加到该窗口,设置对应frame
- 强引用持有控制器,防止被内存释放
代码示例(Objective-C):
// 强引用持有控制器 @property (nonatomic, strong) YourTargetViewController *topVC; - (void)showTopVCOnWindow { self.topVC = [[YourTargetViewController alloc] init]; // iOS13+ 获取当前活跃场景的窗口 UIWindowScene *activeScene = (UIWindowScene *)[[UIApplication sharedApplication].connectedScenes filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) { return [(UIWindowScene *)evaluatedObject activationState == UISceneActivationStateForegroundActive]; }]].firstObject; UIWindow *topWindow = activeScene.windows.lastObject; // 添加控制器view到顶层窗口 [topWindow addSubview:self.topVC.view]; self.topVC.view.frame = topWindow.bounds; }
关键注意事项
- 内存管理:必须用强引用持有自定义window或目标控制器,否则会被系统释放导致视图消失
- 多场景适配:iOS13及以上要针对活跃场景处理,不要直接用
[UIApplication sharedApplication].keyWindow(该API已废弃) - 事件交互:如果需要目标控制器接收触摸事件,方案一中可以调用
makeKeyAndVisible,方案二中确保控制器的view层级在最上层(可设置self.topVC.view.layer.zPosition = MAXFLOAT)
内容的提问来源于stack exchange,提问作者Tometoyou
相关产品推荐
相关产品推荐

