昨天想写个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];
}