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];
}

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