用XCode 11 創(chuàng)建的工程
在Xcode 11 創(chuàng)建的工程,運(yùn)行設(shè)備選擇 iOS 13.0 以下的設(shè)備,運(yùn)行應(yīng)用時(shí)會(huì)出現(xiàn)黑屏現(xiàn)象。
原因:
??1. Xcode 11 默認(rèn)是會(huì)創(chuàng)建通過(guò) UIScene 管理多個(gè) UIWindow 的應(yīng)用,工程中除了 AppDelegate 外會(huì)多一個(gè) SceneDelegate;
?? 2. AppDelegate和SceneDelegate這是iPadOS帶來(lái)的新的多窗口支持的結(jié)果,并且有效地將應(yīng)用程序委托的工作分成兩部分。
也就是說(shuō)在我們用多窗口開(kāi)發(fā)iPadOS中,從iOS 13開(kāi)始,您的應(yīng)用代表應(yīng)該:
?? 1. 設(shè)置應(yīng)用程序期間所需的任何數(shù)據(jù)。
?? 2. 響應(yīng)任何專(zhuān)注于應(yīng)用的事件,例如與您共享的文件。
?? 3. 注冊(cè)外部服務(wù),例如推送通知。
?? 4. 配置您的初始場(chǎng)景。
?? 相比之下,在iOS 13中的新頂級(jí)對(duì)象是一個(gè)UIWindowScene,場(chǎng)景代表可以處理應(yīng)用程序用戶界面的一個(gè)實(shí)例。因此,如果用戶創(chuàng)建了兩個(gè)顯示您的應(yīng)用程序的窗口,則您有兩個(gè)場(chǎng)景,均由同一個(gè)應(yīng)用程序委托支持。
?? 這些場(chǎng)景旨在彼此獨(dú)立工作。因此,您的應(yīng)用程序不再移動(dòng)到后臺(tái),而是單個(gè)場(chǎng)景執(zhí)行 - 用戶可以將一個(gè)移動(dòng)到后臺(tái),同時(shí)保持另一個(gè)打開(kāi)。
我們可以看下info.plist文件和工程項(xiàng)目文件的變化如圖:


適配方案一
如果我們不開(kāi)發(fā)iPadOS多窗口APP,SceneDelegate窗口管理我們可以不需要直接刪掉就好了。
- 刪除掉info.plist中Application Scene Manifest選項(xiàng),同時(shí),文件SceneDelegate可刪除可不刪;
- appdelegate.m中UISceneSession相關(guān)代碼刪掉;
#pragma mark - UISceneSession lifecycle
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options API_AVAILABLE(ios(13.0));{
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}
- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions API_AVAILABLE(ios(13.0));{
// 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.
}
- Appdelegate新增windows屬性
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
適配方案二
即要用iOS 13中新的SceneDelegate,又可以在iOS 13一下的設(shè)備中完美運(yùn)行。那就添加版本判斷,利用@available
步驟:
- SceneDelegate中每個(gè)方法添加
API_AVAILABLE(ios(13.0)),如下
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session
options:(UISceneConnectionOptions *)connectionOptions
API_AVAILABLE(ios(13.0)){
}
切記:這種方式,AppDelegate中的有關(guān)程序的一下?tīng)顟B(tài)的方法,iOS 13設(shè)備是不會(huì)走的,iOS13一下的是會(huì)收到事件回調(diào)的。13以上的設(shè)備會(huì)走SceneDelegate對(duì)應(yīng)的方法
func applicationWillResignActive(_ application: UIApplication) {
}
.....
.....
.....