Xcode 11新建工程
在Xcode 11 創(chuàng)建的工程匹摇,運(yùn)行設(shè)備選擇 iOS 13.0 以下的設(shè)備贿衍,運(yùn)行應(yīng)用時(shí)會出現(xiàn)黑屏現(xiàn)象汰翠。
原因:
? ? Xcode 11 默認(rèn)是會創(chuàng)建通過 UIScene 管理多個(gè) UIWindow 的應(yīng)用,工程中除了 AppDelegate 外會多一個(gè) SceneDelegate
? ? AppDelegate和SceneDelegate這是iPadOS帶來的新的多窗口支持的結(jié)果焙格,并且有效地將應(yīng)用程序委托的工作分成兩部分卧土。
也就是說在我們用多窗口開發(fā)iPadOS中惫皱,從iOS 13開始,您的應(yīng)用代表應(yīng)該:
? ? 設(shè)置應(yīng)用程序期間所需的任何數(shù)據(jù)尤莺。
? ? 響應(yīng)任何專注于應(yīng)用的事件旅敷,例如與您共享的文件。
? ? 注冊外部服務(wù)颤霎,例如推送通知媳谁。
? ? 配置您的初始場景。
相比之下友酱,在iOS 13中的新頂級對象是一個(gè)UIWindowScene晴音,場景代表可以處理應(yīng)用程序用戶界面的一個(gè)實(shí)例。因此缔杉,如果用戶創(chuàng)建了兩個(gè)顯示您的應(yīng)用程序的窗口锤躁,則您有兩個(gè)場景,均由同一個(gè)應(yīng)用程序委托支持或详。
這些場景旨在彼此獨(dú)立工作进苍。因此,您的應(yīng)用程序不再移動到后臺鸭叙,而是單個(gè)場景執(zhí)行 - 用戶可以將一個(gè)移動到后臺,同時(shí)保持另一個(gè)打開拣宏。
我們可以看下info.plist文件和工程項(xiàng)目文件的變化如圖:
在這里插入圖片描述
在這里插入圖片描述
適配方案一
如果我們不開發(fā)iPadOS多窗口APP沈贝,SceneDelegate窗口管理我們可以不需要直接刪掉就好了。
? ? 刪除掉info.plist中Application Scene Manifest選項(xiàng)勋乾,同時(shí)宋下,文件SceneDelegate可刪除可不刪
? ? 相關(guān)代碼注釋掉
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>) {
? ? }
? ? //注釋掉這兩個(gè)方法嗡善。
? ? 1
? ? 2
? ? 3
? ? 4
? ? 5
? ? 6
? ? 7
? ? 8
? ? Appdelegate新增windows屬性
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//如果是用默認(rèn)的storyboard,下面的代碼可以不寫
//? ? ? ? window = UIWindow.init()
//? ? ? ? window?.frame = UIScreen.main.bounds
//? ? ? ? window?.makeKeyAndVisible()
//? ? ? ? window?.rootViewController = UIStoryboard.init(name: "Main", bundle: nil).instantiateInitialViewController()
? ? ? ? return true
? ? }
? ? ///做完這些就跟以前一樣啦学歧。
? ? 1
? ? 2
? ? 3
? ? 4
? ? 5
? ? 6
? ? 7
? ? 8
? ? 9
? ? 10
? ? 11
適配方案二
即要用iOS 13中新的SceneDelegate罩引,又可以在iOS 13一下的設(shè)備中完美運(yùn)行。那就添加版本判斷枝笨,利用@available
步驟:
? ? SceneDelegate中添加@available(iOS 13, *)
@available(iOS 13, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
//在類的頭部@available(iOS 13, *)添加即可
........
........
.......
}
? ? 1
? ? 2
? ? 3
? ? 4
? ? 5
? ? 6
? ? 7
? ? AppDelegate中同樣聲明window屬性
var window: UIWindow?
///didFinishLaunchingWithOptions中添加版本判斷
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 13, *) {
? ? ? }else {
? ? ? ? ? ? window = UIWindow.init()
? ? ? ? ? ? window?.frame = UIScreen.main.bounds
? ? ? ? ? ? window?.makeKeyAndVisible()
? ? ? ? ? ? window?.rootViewController = UIStoryboard.init(name: "Main", bundle: nil).instantiateInitialViewController()
? ? ? ? }
? ? ? ? return true
? ? }
? ? 1
? ? 2
? ? 3
? ? 4
? ? 5
? ? 6
? ? 7
? ? 8
? ? 9
? ? 10
? ? 11
? ? 12
? ? AppDelegate中兩個(gè)關(guān)于Scene的類也添加版本控制袁铐,Swift中可以用擴(kuò)展單獨(dú)拎出來,如下:
@available(iOS 13.0, *)
extension AppDelegate {
? ? // MARK: UISceneSession Lifecycle
? ? 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>) {
? ? }
}
///完工
? ? 1
? ? 2
? ? 3
? ? 4
? ? 5
? ? 6
? ? 7
? ? 8
? ? 9
? ? 10
? ? 11
? ? 12
切記:這種方式横浑,AppDelegate中的有關(guān)程序的一下狀態(tài)的方法剔桨,iOS 13設(shè)備是不會走的,iOS13一下的是會收到事件回調(diào)的徙融。13以上的設(shè)備會走SceneDelegate對應(yīng)的方法
func applicationWillResignActive(_ application: UIApplication) {
? }
? .....
? .....
? .....
———————————————