我们把Xcode升级到11.0以后,新建工程的时候就会多一个SceneDelegate 文件,这是苹果兼容iPadOS新添加的文件。
1、 Xcode 11 默认是会创建通过 UIScene 管理多个 UIWindow 的应用,工程中除了 AppDelegate 外会多一个 SceneDelegate
2、AppDelegate和SceneDelegate这是iPadOS带来的新的多窗口支持的结果,并且有效地将应用程序委托的工作分成两部分。
那AppDelegate 和 SceneDelegate到底有什么区别
- 在iOS 13以后
AppDelegate
的功能发生了变化,把一部分功能交给了SceneDelegate
处理
在iOS13 以前AppDelegate
的功能,全权处理App生命周期和UI生命周期,如下图。
- 在iOS 13以后
AppDelegate
的功能 和SceneDelegate
功能对照图
SceneDelegate适配
方案一
如果我们不开发iPadOS多窗口APP,SceneDelegate窗口管理我们可以不需要直接删掉就好了。
1.删除掉info.plist中Application Scene Manifest选项,同时,文件SceneDelegate可删除可不删
2.相关代码注释掉
//注释下面两个方法func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)}func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {}
//在AppDelegate 中添加window 属性var window: UIWindow?func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {// Override point for customization after application launch.window = UIWindow.init()window?.frame = UIScreen.main.boundswindow?.makeKeyAndVisible()window?.rootViewController = UIViewController.init()return true}
方案二
即要用iOS 13中新的SceneDelegate,又可以在iOS 13一下的设备中完美运行。那就添加版本判断,利用@available
1.SceneDelegate中添加@available(iOS 13, *)
import UIKit
@available(iOS 13, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {var window: UIWindow?func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {let windowScene:UIWindowScene = scene as! UIWindowScenewindow = UIWindow.init(windowScene: windowScene)window?.backgroundColor = UIColor.greenwindow?.frame = UIScreen.main.boundswindow?.makeKeyAndVisible()let tt = UIViewController.init()tt.view.backgroundColor = UIColor.brownwindow?.rootViewController = ttguard let _ = (scene as? UIWindowScene) else { return }}
}
2.AppDelegate中同样声明window属性,AppDelegate中两个关于Scene的类也添加版本控制,Swift中可以用扩展单独拎出来,如下:
@UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {var window: UIWindow?func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {// Override point for customization after application launch.if #available(iOS 13, *) {}else {window = UIWindow.init()window?.frame = UIScreen.main.boundswindow?.makeKeyAndVisible()window?.rootViewController = UIViewController.init()}return true}}@available(iOS 13.0, *)
extension AppDelegate {// MARK: UISceneSession Lifecyclefunc application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)}func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {}
}
本文参考1:https://blog.csdn.net/weixin_38735568/article/details/101266408
本文参考2:https://www.jianshu.com/p/801de3beee22