首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iPadOS上启动黑屏翻车问题分析(二)

iPadOS上启动黑屏翻车问题分析(二)

作者头像
大话swift
发布2019-10-14 18:07:50
1.9K0
发布2019-10-14 18:07:50
举报
文章被收录于专栏:大话swift大话swift

iPadOS上启动黑屏翻车问题分析(一)

昨天我们说了旧的项目在iOS 13下完全启动之后黑屏的问题,然后紧跟问题通过UI图层分析方式一步步的分析基本找到了问题的根源---iPadOS的底层以及操作思路转变啦

单窗口时代

咱们暂且吧单窗口的iOS定义为旧时代,也就是之前的iOS应用默认的情况下基于单一窗口模式开发的(如下图),而作为开发人员也是十分的享受这种内置的开发模版

新的时代--支持多窗口模式

在升级到iOS 13之后系统开始支持多窗口这个尤其是在iPadOS上尤为显著,这样你可以同时的在一个设备屏幕上同时享受到至少两个App的视图内容…

AppDelegate对App管理权限的转移

我们提到之前的iOS App是基于单视窗的而我们在开发中也是默认情况下不去而外的去添加新的window,因此在这种情况下我们的APPDelegate就成了整个App的生命周期的管理者啦。但是iOS 13之后这个规律被打破,将很多的任务转移给了UIWindowScene

旧项目黑屏拯救

既然App的声明周期在转移那么我们的App代码也要跟着迁移处理

1 Info.plist更改

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>UIApplicationSupportsMultipleScenes</key>
  <true/>
  <key>UISceneConfigurations</key>
  <dict>
    <key>UIWindowSceneSessionRoleApplication</key>
    <array>
      <dict>
        <key>UISceneDelegateClassName</key>
        <string>$(TARGET_NAME).SceneDelegate</string>
        <key>UISceneStoryboardFile</key>
        <string>Main</string>
        <key>UISceneConfigurationName</key>
        <string>Default Configuration</string>
      </dict>
    </array>
  </dict>
</dict>
</plist>

Swift来说由于一般情况下

OC项目配置

从plist配置来看的话,我们需要新建一个类来作为WindowScene的代理的载体

②对APPDelegate的修改

OC版本

-(UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options API_AVAILABLE(ios(13.0)){
    UISceneConfiguration * config = [[UISceneConfiguration alloc] initWithName:@"Default" sessionRole:connectingSceneSession.role];
    
    return config;
}

Swift版本

    func application(_ application: UIApplication,
                     configurationForConnecting connectingSceneSession: UISceneSession,
                     options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

从API_AVAILABLE(ios(13.0))的attribute可知这个会在iOS13才会调用,我们做好版本兼容即可

③ 新建的SceneDelegate载体

OC版本

.m文件

#import "SceneDelegate.h"
#import "LoginViewController.h"
@interface SceneDelegate()

@end
@implementation SceneDelegate
-(void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions API_AVAILABLE(ios(13.0)){
         UIWindow * aWindow = [[UIWindow alloc] initWithWindowScene:scene];
    
    aWindow.rootViewController = [[LoginViewController alloc] init];
    self.window = aWindow;
    [self.window makeKeyAndVisible];
    AppDelegate *app = [UIApplication sharedApplication].delegate;
    [app setWindow:self.window];
 }
@end

上篇文章我们分析到UIWindow的继承关系发生了变化需要通过Scene来进行初化,而Scene变化为称为Respender的子类可以响应事件而不再是之前那个单纯的UIScene

在这个为了对以前的代码的支持我们依然给AppDelegate一个window,但是这个已经不是之前项目那个widow那么简单啦

Swift版本我们就不详细说了代码逻辑依然是OC的


class SceneDelegate: UIResponder,UIWindowSceneDelegate {
    var window: UIWindow?
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        var aWindow = UIWindow(windowScene: scene as! UIWindowScene)
        aWindow.rootViewController = LoginViewController()
        
        self.window = aWindow
        self.window?.makeKeyAndVisible()
        var app: AppDelegate = UIApplication.shared.delegate as! AppDelegate
        app.window = window
    }
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大话swift 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档