iOS开发:UIScene与UIWindow的区别及多实例场景应用疑问
UIScene与UIWindow核心疑问解答
一、图片内容判定:两个独立场景
根据苹果官方定义:
场景(
UIScene)代表您应用用户界面的一个实例
窗口(UIWindow)是您应用用户界面的背景,以及将事件分发到视图的对象
结合图片展示的「同一应用的两个独立可交互UI实例」特征,这属于两个独立的UIScene。核心依据是:每个场景对应一个完整独立的UI运行上下文,用户可对两个UI实例进行完全独立的操作(如分别导航、编辑内容);而单场景下的多窗口,本质是同一UI上下文内的多层视图容器,共享同一个场景的生命周期与状态。
二、多场景与单场景多窗口的设计目的、区别及用法
1. 多应用场景(UIScene)
- 设计目的:
- 适配iPad、Mac Catalyst等平台的多窗口运行模式,支持用户同时打开同一应用的多个独立会话(如同时编辑两份备忘录)
- 实现App Clip、Widget Extension等轻量UI载体的独立运行
- 达成应用状态隔离,不同场景拥有独立的生命周期回调与存储状态
- 核心特性:
- 每个场景对应独立的
UIWindowScene(场景子类),作为窗口层级的根节点 - 场景间状态完全隔离,系统内存不足时可单独挂起某一场景,不影响其他场景运行
- 每个场景对应独立的
- 典型用法:
- iPad的应用分屏、Slide Over多窗口模式
- Mac Catalyst应用的多窗口打开
- 邮件App中同时打开两个独立的邮件编辑会话
2. 单场景多窗口(UIWindow)
- 设计目的:
- 在同一UI上下文内实现多层级UI展示,如弹窗、悬浮面板、画中画等
- 无需启动新场景即可实现临时的、依赖主场景状态的UI扩展
- 核心特性:
- 所有窗口共享所属场景的生命周期与状态,跟随场景的前后台状态同步变化
- 通过
windowLevel属性区分层级,高优先级窗口会覆盖低优先级窗口
- 典型用法:
- 全局权限请求弹窗
- 视频播放的画中画窗口
- 自定义悬浮操作面板
3. 核心区别对比
| 维度 | 多UIScene | 单场景多UIWindow |
|---|---|---|
| 状态隔离 | 完全独立,各场景拥有专属状态存储 | 共享场景状态,窗口依赖主场景数据 |
| 生命周期管理 | 系统独立管理每个场景的前后台状态 | 跟随所属场景生命周期,无独立回调 |
| 资源占用 | 较高,每个场景需独立初始化上下文 | 较低,复用现有场景的上下文资源 |
| 用户交互独立性 | 可独立操作每个场景的UI | 窗口依附主场景,操作受主场景限制 |
三、Objective-C示例代码
1. 配置多场景支持(iPad多窗口)
// AppDelegate.m - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { application.applicationSupportsMultipleScenes = YES; return YES; } // SceneDelegate.m - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { UIWindowScene *windowScene = (UIWindowScene *)scene; self.window = [[UIWindow alloc] initWithWindowScene:windowScene]; self.window.rootViewController = [[UIViewController alloc] init]; [self.window makeKeyAndVisible]; }
2. 在单场景中添加悬浮窗口
// ViewController.m - (void)createFloatingWindow { UIWindowScene *currentScene = (UIWindowScene *)self.view.window.windowScene; UIWindow *floatingWindow = [[UIWindow alloc] initWithWindowScene:currentScene]; floatingWindow.windowLevel = UIWindowLevelAlert + 1; // 设置更高层级 floatingWindow.frame = CGRectMake(50, 50, 300, 200); floatingWindow.backgroundColor = [UIColor whiteColor]; UIViewController *floatingVC = [[UIViewController alloc] init]; floatingVC.view.backgroundColor = [UIColor lightGrayColor]; floatingWindow.rootViewController = floatingVC; [floatingWindow makeKeyAndVisible]; }
内容的提问来源于stack exchange,提问作者enell
相关产品推荐
相关产品推荐

