先说结论:
SceneDelegate 用于 iPad 分屏 APP 开发, 目前 iPhone 没有分屏
纯代码, 不使用 StoryBoard
和 xib
在 Xcode 11 和 iOS 13 中新增了 SceneDelegate
, SceneDelegate
的 scene
代替了 AppDelegate
的 window
-
window
就是应用程序, 只有一个, 所有操作, 都在 window 中 -
scene
场景, 应用程序可以有多个场景, 每个场景都有一个 window
UISceneDelegate
Working with Window Scenes
Supporting Multiple Windows on iPad
Support side-by-side instances of your app’s interface and create new windows.
使用窗口场景
支持iPad上的多个窗口
支持应用界面的并行实例并创建新窗口。
AppDelegate (Xcode10 / iOS12 及之前)
AppDelegate
全权处理 App生命周期 和 UI生命周期
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let nav = UINavigationController(rootViewController: ViewController())
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = nav
window?.makeKeyAndVisible()
return true
}
// MARK: UIApplicationDelegate
@available(iOS 2.0, *)
optional func applicationDidBecomeActive(_ application: UIApplication)
@available(iOS 2.0, *)
optional func applicationWillResignActive(_ application: UIApplication)
@available(iOS 4.0, *)
optional func applicationDidEnterBackground(_ application: UIApplication)
@available(iOS 4.0, *)
optional func applicationWillEnterForeground(_ application: UIApplication)
AppDelegate + SceneDelegate (Xcode11 / iOS13)
-
AppDelegate
处理 App生命周期 和 SceneSession 生命周期 -
SceneSession
负责 UI生命周期
新项目变化
-
AppDelegate.swift
只配置UISceneConfiguration
, 不再管理window
,
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
// 退出场景, 不会被重新连接
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
- 新增了
SceneDelegate.swift
文件, 管理场景的生命周期,处理各种响应
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
// 与 didFinishLaunchingWithOptions 类似, 配置场景
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let windowScene: UIWindowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
self.window = window
let nav = UINavigationController(rootViewController: ViewController())
window.rootViewController = nav
window.makeKeyAndVisible()
}
// 当场景与app断开连接 (还可能重新连接)
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}
// 与 AppDelegate 的 applicationDidBecomeActive 类似
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
// 与 AppDelegate 的 applicationWillResignActive 类似
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
// 与 AppDelegate 的 applicationWillEnterForeground 类似
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
// 与 AppDelegate 的 applicationDidEnterBackground 类似
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}
-
Info.plist
新增了Application Scene Manifest
<plist version="1.0">
<dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
</dict>
</plist>
新项目删除 SceneDelegate
- 删除
SceneDelegate.swift
- 删除
Info.plist
新增了UIApplicationSceneManifest
- 删除
AppDelegate.swift
中的scene
相关方法 - 修改
LaunchScreen.storyboard
启动页面