基於Xcode11創建自定義UIWindow手記

筆者最近更新Xcode 11.4,在創建項目之後發現多了蘋果分屏技術,新增了SceneDelegate這個文件,另外AppDelegate文件結構也發生了變化,給人一種似曾相識又不同的感覺,總的來說之前熟悉的Window不再由AppDelegate管理,而是交給了SceneDelegate。

如下圖即可看出目錄結構和info配置變化:

簡要介紹Application Scene Manifest分屏配置:

enable Multipe Windows --- 是否允許分屏
Scene Configuratiton --- 屏幕配置項
Application Session Role --- 程序屏幕配置規則(爲每個Scene指定規則)
Configuration Name --- 配置名稱
Delegate Class Name --- 代理類名稱
Storyboard Name --- Storyboard名稱

解讀如下:

創建項目工程時,系統默認爲我們創建了一個名爲Default Configuratiton 的默認配置,代理類名稱爲SceneDelegate,入口名爲MainStoryboard,代碼如下:

- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}

回到主題,針對這種情況,如果創建我們熟悉的自定義Window呢?

一、針對iOS13系統及以上:保留SceneDelegate,需要修改SceneDelegate裏面的代碼即可;

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    
    
    if (@available(ios 13, *)) {
        if (scene) {
            self.window = [[UIWindow alloc] initWithWindowScene:(UIWindowScene *)scene];
            self.window.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
            UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc]init]];
            self.window.rootViewController = nav;
            [self.window makeKeyAndVisible];
        }
    }
}

效果圖:

 

二、針對iOS13系統以下:

a. 刪除info.plist文件中的Application Scene Manifest選項;

b. 刪除SceneDelegate文件;

c. 刪除AppDelegate裏面的UISceneSession lifecycle方法;

d. AppDelegate頭文件添加window屬性;

@property (strong, nonatomic) UIWindow *window;

e. 修改AppDelegate啓動方法:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    ViewController *vc = [[ViewController alloc]init];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];
    return YES;
}

效果圖:

至此,我們又回到了曾經熟悉的開發場景。

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