iOS多用户界面场景UIWindowScene
iOS多用户界面场景UIWindowScene

iOS多用户界面场景UIWindowScene

UIWindowScene 是 UIScene 的一个子类,是最常见的 Scene 类型,表示一个拥有一个或多个窗口 (UIWindow) 的用户界面场景。

类定义

class UIWindowScene : UIScene

它主要用于 iOS 13+ 的多窗口架构中,尤其是在 iPad 上。

每一个 UIWindowScene 代表一个独立的用户交互窗口环境(例如一个 App 的窗口或分屏实例)。

主要用途

UIWindowScene 主要用于管理以下内容:

1、UIWindow:该场景下所有窗口(通常只有一个)。

2、size, traitCollection:场景的屏幕尺寸、大小类等。

3、interfaceOrientation:当前界面方向。

4、statusBarManager:状态栏管理器。

5、screen:该窗口场景所在的屏幕(支持外接屏)。

场景创建(在 SceneDelegate.swift)

在 iOS 13+,我们通过 SceneDelegate 设置 UIWindowScene 的主窗口:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    guard let windowScene = (scene as? UIWindowScene) else { return }
    
    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = MyRootViewController()
    self.window = window
    window.makeKeyAndVisible()
}

获取UIScene对象

当调用:

UIApplication.shared.connectedScenes

返回的是一组 UIScene 对象,其中大部分是 UIWindowScene(表示界面窗口的场景):

let windowScenes = UIApplication.shared.connectedScenes
    .compactMap { $0 as? UIWindowScene }

判断“当前前台活跃”的窗口场景

let foregroundScene = UIApplication.shared.connectedScenes
    .first { $0.activationState == .foregroundActive } as? UIWindowScene

这就是在 iPad 多窗口环境中,获取“当前用户正在操作”的那个窗口。

UIApplication.shared.connectedScenes 是什么?

这是一个 Set<UIScene> 类型,表示当前 App 所有“已连接”的场景(Scene),这些场景可能是:

1、UIWindowScene(用得最多的,代表 UI 界面)。

2、其他类型的 UIScene(理论上支持,但很少见,目前几乎都只有 UIWindowScene)。

是在过滤出真正用于 UI 显示的场景。

activationState == .foregroundActive 的作用是什么?

这个是用于判断每个 UIWindowScene 的当前状态:

1、.foregroundActive: 正在前台活动(用户当前正在看)。

2、.foregroundInactive: 前台但不活跃(比如有电话进来)。

3、.background: 已经进入后台。

4、.unattached: 尚未连接(极少出现)。

iPhone 场景

正常情况下只会有一个 foregroundActive 的 UIWindowScene。

iPad 场景(多窗口)

可以有多个 UIWindowScene 是 .foregroundActive。

比如Split View(分栏)或 Slide Over(滑出窗口)。

UIApplication.shared.connectedScenes
    .compactMap { $0 as? UIWindowScene }
    .filter { $0.activationState == .foregroundActive }

这个可以拿到多个活跃窗口。

常见场景

每个 UIWindowScene 管理自己的:

1、UIWindow。

2、rootViewController。

3、状态栏。

4、分屏尺寸等。

UIWindowScene和UIWindow的关系

1、正常情况下:一个 UIWindowScene 只包含一个 UIWindow

这是最常见也是默认的情况,App(不管是 iPhone 还是 iPad)——

UIApplication.shared.connectedScenes.first as? UIWindowScene

通常就有:

一个 UIWindowScene。

一个 UIWindow(就是主界面)。

一个 rootViewController(管理视图)。

2、多个UIWindow的情况

这是 UIKit 提供的能力,但一般开发者不会主动用到。

UIWindowScene.windows 是一个数组,这说明它确实可以持有多个 UIWindow。

在App中弹出键盘、通知中心、Siri或控制中心等窗口时,每个窗口都是一个UIWindow,但它们可能会挂载到系统级UIWindowScenes行。

开发者还可以自定义多个UIWindow,例如悬浮窗、弹出看蒙层等UIWindow。

let newWindow = UIWindow(windowScene: windowScene)
newWindow.rootViewController = ...
newWindow.windowLevel = .alert + 1
newWindow.makeKeyAndVisible()

这时app就会有两个UIWindow挂在同一个UIWindowScene上。

但绝大多数App只用一个UIWindow,这是因为一个UIWindow就可以:

1、展示主视图。

2、展示弹窗(UIAlertController是在rootViewController上present的,不需要新的window)。

3、切换视图也是在ViewController层做的。

总结

UIWindowScene 是 iOS 13+ 多窗口支持的核心类,代表一个“UI 窗口实例”,是 UIScene 的子类,管理窗口尺寸、方向、状态栏等,并承载一个或多个 UIWindow。

相关文章

1、iOS支持多窗口的UIScene:https://fangjunyu.com/2025/05/21/ios%e6%94%af%e6%8c%81%e5%a4%9a%e7%aa%97%e5%8f%a3%e7%9a%84uiscene/

2、iOS界面UIView:https://fangjunyu.com/2025/05/20/ios%e7%95%8c%e9%9d%a2uiview/

3、iOS窗口容器UIWindow:https://fangjunyu.com/2025/05/20/ios%e7%aa%97%e5%8f%a3%e5%ae%b9%e5%99%a8uiwindow/

4、iOS管理多窗口的SceneDelegate:https://fangjunyu.com/2025/05/20/ios%e7%ae%a1%e7%90%86%e5%a4%9a%e7%aa%97%e5%8f%a3%e7%9a%84scenedelegate/

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注