UIScene in iOS
UIScene
是iOS 13引入的,核心要解决的是,原来的基于1个Window管理App UI的策略,不能很好的适配像iPad中出现的一个App对应多个Window的场景
iOS 13之前
在iOS 13以前,App启动后执行的方法以及AppDelegate所负责的工作如下图所示
- App Delegate一方面要负责App进程生命周期方法执行、事件回调
- 另一方面还要处理UI的生命周期
iOS 13开始
从iOS 13开始,变化如下:
- 关于App进程生命周期,还是App Delegate在负责,保持不变
- 但UI生命周期的管理则是交给了
Scene Delegate
这也就引出了Scene、Scene Delegate、UIWindowScene等概念。最核心的理念在于:
原来是一个App进程对应一个UI场景;现在开始,一个App进程将对应多个UI场景,其中的每一个场景都叫做
Scene
既然引入了场景Scene
,那场景所对应的实例(UIScene
、UIWindowScene
)、代理(Scene Delegate
)、场景管理的window等概念也就非常合理了
对于上图,还有几点需要关注:
- App Delegate中负责创建、切换
Scene
- 当实现
Scene Delegate
中的各种UI回调后,原来App Delegate的UI回调变不再执行 - 由于一个App进程可能有多个
Scene
,所以App Delegate中也会有Scene
创建、连接、断开连接、销毁等逻辑,这一点在后面的图中更能看出来
引入Scene后的App启动流程
Q&A
1. iPhone是否支持多个Scene
不支持
尽管官方文档中说iOS支持,但通过UIApplication.shared.supportsMultipleScenes
结果来看,iOS应用并不支持
2. 一个Scene是只对应一个Window吗
- 不是的,可以对应多个Window,可以通过API
UIWindowScene.windows
了解到 - 尽管如此,大部分情况下一个Scene只有1个Window
3. 如何初始化Scene
开发者不要直接创建UIWindowScene
实例,而是交给系统创建,创建方式有如下几种:
- 通过在Info.plist中scene配置中指定scene的类名
- 或者在app delegate的
application(_:configurationForConnecting:options:)
方法中,创建UISceneConfiguration
时指定scene的类名 - 也可以通过嗲用
UIApplication.requestSceneSessionActivation(_:userActivity:options:errorHandler:)
方法来获取/创建scene实例