关于iOS13 Scenedelegate

1,061 阅读2分钟

SceneDelegate是在iOS13之后出现的一个新的类。

iOS13之前,窗口Windows是在APPdelegate里面。
iOS13之后,窗口Windows是写在了SceneDelegate里面。

iOS13之前:APPdelegate处理APP的生命周期以及UI的生命周期
iOS13之后:APPdelegate处理APP的生命周期以及SceneDelegate的生命周期。

适配方案

一、不支持多窗口

①删除SceneDelegate代理文件 (可选)

image.png

②删除 Info.plist里面的Application Scene Manifest配置(一定要删除)

image.png ③删除 AppDelegate代理的两个方法

image.png

注:这两个方法一定要删除,否则使用纯代码创建的Window和导航控制器UINavigationController不会生效。

二、项目支持多场景窗口

1、iOS13及以上版本 在SceneDelegate的方法scene:willConnectToSession:options:中创建UIWindow和UINavigationController

代码如下

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    //设置自己的rootViewController
    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];

}

2、同时兼容iOS13和iOS12及以下 多场景窗口、SceneDelegate等只有在iOS13才可以,若要考虑iOS12及以下的运行环境,那么需考虑环境版本匹配

//注:@available方法 在iOS 10以下调用会闪退,既然是多版本兼容,那还是使用旧的判断版本方式吧

①除了与以前版本一样,要删除Main storyboard file base name之外, 还要在项目Info.plist中, 删除SceneDelegate的StoryboardName

image.png ②AppDelegate.m部分代码

代码如下

#import "AppDelegate.h"

#import "CTTabBarViewController.h"

#define ISIOS(number) ([[[UIDevice currentDevice] systemVersion] floatValue] >= number) ? YES : NO

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // if (@available(iOS 13,*)) { //注:@available 在iOS 10以下调用会闪退,既然是多版本兼容,那还是使用旧的判断版本方式吧

    if (ISIOS(13.0)) {

    return YES;

    } else {

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

    CTTabBarViewController *vc = [[CTTabBarViewController alloc] init];

    // UINavigationController *rootNavgationController = [[UINavigationController alloc] initWithRootViewController:[ViewController new]];

    self.window.rootViewController = vc;

    [self.window makeKeyAndVisible];

    return YES;

    }

}

③SceneDelegate部分代码

代码如下

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {

    if (scene) {

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

    if (@available(iOS 13.0, *)) { //注:@available 在iOS 10以下调用会闪退

    self.window.windowScene = (UIWindowScene*)scene;

    CTTabBarViewController *vc = [[CTTabBarViewController alloc] init];

    // UINavigationController *rootNavgationController = [[UINavigationController alloc] initWithRootViewController:[ViewController new]];

    self.window.rootViewController = vc;

    [self.window makeKeyAndVisible];

    } else {

    }

    } else {

    }

}