昨天想寫個demo,創建了一個項目發現項目的文件列表裏多了一個SceneDelegate文件,剛開始沒注意就直接寫代碼,結果發現AppDelegate中設置window的rootViewController沒有用。
沒辦法,找問題找答案。😂😂😂
去看了官方視頻文檔WWDC2019:Optimizing App Launch發現了問題所在(地址:https://developer.apple.com/videos/play/wwdc2019/423/)。原來在iOS13之前是AppDelegate管理app和UI的生命週期,在iOS13之後AppDelegate管理app的生命週期和SceneDelegate的生命週期,將UI的生命週期交給SceneDelegate管理,這也就是爲什麼在SceneDelegate.h中有個window。
所以,在Xcode11之後創建項目,在設置setRootViewController不能在AppDelegate的
-
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
方法中了,而是在SceneDelegate的 -
(void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions;
方法裏設置。代碼示例如下:
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
UIWindowScene *windowScene = (UIWindowScene *)scene;
self.window = [[UIWindow alloc] initWithWindowScene:windowScene];
self.window.frame = windowScene.coordinateSpace.bounds;
self.window.backgroundColor = [UIColor whiteColor];
SUFirstViewController *firstVC = [[SUFirstViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:firstVC];
[self.window setRootViewController:nav];
[self.window makeKeyAndVisible];
}
SceneDelegate的作用是爲了設置多個scene,可以理解爲分屏,要是不想分屏,可以不用SceneDelegate,直接刪除這個類並在info.plist文件中刪除Application Scene Manifest選項。如下圖:
在AppDelegate.m中註釋掉下面的代碼:
如果因項目需要分屏,並且需要適配iOS13以下,就需要在AppDelegate的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
方法中去加判斷。代碼如下:(別忘了在AppDelegate添加window屬性)
if (@available(iOS 13,*)) {
return YES;
} else {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UINavigationController *rootNavgationController = [[UINavigationController alloc] initWithRootViewController:[ViewController new]];
self.window.rootViewController = rootNavgationController;
[self.window makeKeyAndVisible];
return YES;
}
同時在SceneDelegate中寫window設置代碼:
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.windowScene = (UIWindowScene*)scene;
UINavigationController *rootNavgationController = [[UINavigationController alloc] initWithRootViewController:[ViewController new]];
self.window.rootViewController = rootNavgationController;
[self.window makeKeyAndVisible];
}