iOS 13 SceneDelegate适配

1 篇文章 0 订阅
1 篇文章 0 订阅

Xcode 11新建工程

在Xcode 11 创建的工程,运行设备选择 iOS 13.0 以下的设备,运行应用时会出现黑屏现象。
原因

  1. Xcode 11 默认是会创建通过 UIScene 管理多个 UIWindow 的应用,工程中除了 AppDelegate 外会多一个 SceneDelegate
  2. AppDelegate和SceneDelegate这是iPadOS带来的新的多窗口支持的结果,并且有效地将应用程序委托的工作分成两部分。

也就是说在我们用多窗口开发iPadOS中,从iOS 13开始,您的应用代表应该:

  1. 设置应用程序期间所需的任何数据。
  2. 响应任何专注于应用的事件,例如与您共享的文件。
  3. 注册外部服务,例如推送通知。
  4. 配置您的初始场景。

相比之下,在iOS 13中的新顶级对象是一个UIWindowScene,场景代表可以处理应用程序用户界面的一个实例。因此,如果用户创建了两个显示您的应用程序的窗口,则您有两个场景,均由同一个应用程序委托支持。
这些场景旨在彼此独立工作。因此,您的应用程序不再移动到后台,而是单个场景执行 - 用户可以将一个移动到后台,同时保持另一个打开。

我们可以看下info.plist文件和工程项目文件的变化如图:
在这里插入图片描述
在这里插入图片描述

适配方案一

如果我们不开发iPadOS多窗口APP,SceneDelegate窗口管理我们可以不需要直接删掉就好了。

  1. 删除掉info.plist中Application Scene Manifest选项,同时,文件SceneDelegate可删除可不删
  2. 相关代码注释掉

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

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
    }
    //注释掉这两个方法。
  1. Appdelegate新增windows属性
var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
	//如果是用默认的storyboard,下面的代码可以不写
//        window = UIWindow.init()
//        window?.frame = UIScreen.main.bounds
//        window?.makeKeyAndVisible()
//        window?.rootViewController = UIStoryboard.init(name: "Main", bundle: nil).instantiateInitialViewController()
        return true
    }
    ///做完这些就跟以前一样啦。

适配方案二

即要用iOS 13中新的SceneDelegate,又可以在iOS 13一下的设备中完美运行。那就添加版本判断,利用@available

步骤:

  1. SceneDelegate中添加@available(iOS 13, *)
@available(iOS 13, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
//在类的头部@available(iOS 13, *)添加即可
........
........
.......
}
  1. AppDelegate中同样声明window属性
var window: UIWindow?
///didFinishLaunchingWithOptions中添加版本判断
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
	if #available(iOS 13, *) {
      }else {
            window = UIWindow.init()
            window?.frame = UIScreen.main.bounds
            window?.makeKeyAndVisible()
            window?.rootViewController = UIStoryboard.init(name: "Main", bundle: nil).instantiateInitialViewController()
        }
        return true
    }
  1. AppDelegate中两个关于Scene的类也添加版本控制,Swift中可以用扩展单独拎出来,如下:
@available(iOS 13.0, *)
extension AppDelegate {
    // MARK: UISceneSession Lifecycle
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
    }
}

///完工

切记:这种方式,AppDelegate中的有关程序的一下状态的方法,iOS 13设备是不会走的,iOS13一下的是会收到事件回调的。13以上的设备会走SceneDelegate对应的方法

func applicationWillResignActive(_ application: UIApplication) {
   }
   .....
   .....
   .....
  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
`SceneDelegate` 是 iOS 13 引入的新特性,用于管理多场景(multi-scene)应用程序的生命周期和状态。每个场景都代表一个应用程序窗口和相关的视图控制器层次结构。 在使用 `SceneDelegate` 之前,我们需要先创建一个基于 `UIKit` 的应用程序模板。在 Xcode 11 中创建一个新的项目时,默认会自动生成 `SceneDelegate.swift` 文件。如果没有自动生成,可以手动创建。 然后,在 `AppDelegate.swift` 文件中,需要将应用程序的生命周期方法移动到新的 `SceneDelegate.swift` 文件中。例如,将 `application(_:didFinishLaunchingWithOptions:)` 方法移动到 `SceneDelegate.swift` 文件中: ```swift class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { // Create a new UIWindow instance guard let windowScene = (scene as? UIWindowScene) else { return } window = UIWindow(windowScene: windowScene) // Set the root view controller of the window let viewController = ViewController() window?.rootViewController = viewController // Make the window visible window?.makeKeyAndVisible() } // other SceneDelegate methods } ``` 在 `scene(_:willConnectTo:options:)` 方法中,我们需要创建一个新的 `UIWindow` 实例,并设置其根视图控制器。最后,通过调用 `makeKeyAndVisible()` 方法,使窗口可见。 最后,在 `Info.plist` 文件中,需要添加一个新的键值对,以启用多场景支持。在 `Application Scene Manifest` 中添加一个 `Session Role` 为 `UIWindowSceneSessionRoleApplication` 的项。 ```xml <key>UIApplicationSceneManifest</key> <dict> <key>UISceneConfigurations</key> <dict> <key>UIWindowSceneSessionRoleApplication</key> <array> <dict> <key>UISceneConfigurationName</key> <string>Default Configuration</string> <key>UISceneDelegateClassName</key> <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string> <key>UISceneStoryboardFile</key> <string>Main</string> </dict> </array> </dict> </dict> ``` 现在,我们已经成功地启用了多场景支持,并将应用程序的生命周期方法移动到了 `SceneDelegate.swift` 文件中。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值