Xcode 11今后,新建选用Storyboard 的Swift项目,会主动生成一个 SceneDelegate 文件。 假如运用这个默许生成文件,iOS版本就需要保持在13以上。当然,也可以删去这个文件,从头只运用AppDeleagte,回到曾经的姿态。

UIScene 是 iOS13今后,提出的一个新类型,为显示App界面目标,并可以完成多场景界面。在UIKit中,运用 UIWindowScene 替代 UIScene, 用于访问其特点和办法。并且自身的改变,则是运用一个恪守UISceneDelegate的目标进行办理。至于UIWindowScene,便是运用一个恪守UIWindowSceneDelegate的目标进行办理。

UIWindowScene 继承 UIScene, UIWindowSceneDelegate 继承 UISceneDelegate。

在创立项目时主动生成的 SceneDelegate类,则便是一个恪守UIWindowSceneDelegate的目标,在这儿,就可以观察到Scene的一些改变,并根据需要增加自定义的设置。

import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else { return }
        print("Will Connect To Session")
    }
    func sceneDidDisconnect(_ scene: UIScene) {
        print("Scene Did Disconnect")
    }
    func sceneDidBecomeActive(_ scene: UIScene) {
        print("Did Become Active")
    }
    func sceneWillResignActive(_ scene: UIScene) {
        print("Will Resign Active")
    }
    func sceneWillEnterForeground(_ scene: UIScene) {
        print("Will Enter Foreground")
    }
    func sceneDidEnterBackground(_ scene: UIScene) {
        print("Did Enter Background")
    }
}

window 特点,scene 运用的主窗口。

其他办法,则是类似于曾经在 Appdelegate 办理的生命周期,不过现在是和scene有关。

  • 即将衔接 willConnectTo 和 现已失去衔接 did Disconnect
  • 即将进入前台 willEnterForeground 和 现已活动状况 didBecomeActive
  • 即将进入非活动苔 willResignActive 和 现已进入后台 didEnterBackground

现在在相应办法的内部,增加打印信息,来验证一下相关办法的调用时机。

  1. 打开App
Will Connect To Session
Will Enter Foreground
Did Become Active
  1. 退到后台
Will Resign Active
Did Enter Background
  1. 点击app,从头进入前台
Will Enter Foreground
Did Become Active
  1. 切换App,再回来
Will Resign Active
Did Become Active
  1. 完毕App
Will Resign Active
Scene Did Disconnect

可见,参加scene之后,它的改变现已和app的生命周期改变相关起来,与生命周期相关的办理操作,在iOS13今后,都交给了SceneDeleagate。

项目进口

默许状况下,项目选用 Main.storyboard 的方法创立发动app,这种状况下是不需要任何设置的,window 和 scene 就可以树立相关,发动 Main.storybaord 的初始 view controller。

可是,假如选用代码方法创立进口,然后相关scece 和 window,就要手动设置了。

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let winScene = (scene as? UIWindowScene) else { return }
    let win = UIWindow(windowScene: winScene)
    let vc = UIViewController()
    win.rootViewController = vc
    self.window = win
    window!.makeKeyAndVisible()
}

这儿手动装备与scene相关的window,以及装备了 window的 root view controller。

不运用 SceneDelegate

有些状况,新建的项目并不喜欢运用默许生成的SceneDelegate,而是想回到曾经运用AppDelegate 办理App生命周期的状况,完成起来也不难。

关于运用Storyboard作为进口的项目:

  1. 删去项目的SceneDelegate.swift文件。
  2. 在AppDelegate类中增加 var window: UIWindow?特点。
  3. 在 Target 的 Info 选项中,删去 Application Scene Manifestkey 的内容。

从头run 一下,就现已可以了。

别的说一下这个 Application Scene Manifestkey,这个便是项目中运用Scene的装备项,新建项目会默许生成,且多scene,还有scene的装备信息也在这儿。

至于纯代码创立进口,和之前的操作是一样的,不再叙说。

总结

SceneDelegate 的出现,分离了 AppDelegate 的一部分责任功能,这儿主要是一些类似生命周期相关的责任功能,曾经关于生命周期的App装备,现在转到了SceneDelegate中处理。