iOS SceneDelegate

昨天想写个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选项。如下图:
删除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];
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章