支持 iOS 12 和 13 时的 AppDelegate 和 SceneDelegate [英] AppDelegate and SceneDelegate when supporting iOS 12 and 13
问题描述
我需要支持 iOS 12 和 iOS 13.
I need to support iOS 12 and iOS 13.
我应该在 AppDelegate
和 SceneDelegate
之间复制代码吗?
Should I be duplicating code between AppDelegate
and SceneDelegate
?
例如:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
window.rootViewController = HomeViewController()
window.makeKeyAndVisible()
self.window = window
}
和
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = HomeViewController()
window.makeKeyAndVisible()
self.window = window
return true
}
如果我不这样做,在 1 个版本中我最终会出现黑屏,但是如果我这样做并在 HomeViewController
的 viewDidLoad
方法中打印,我可以看到它被调用了两次.
If I don't do this, in 1 version I end up with a black screen, but if I do and print in the viewDidLoad
method of HomeViewController
I can see it is called twice.
我更新了我的 didFinishLaunchingWithOptions
,我可以在 iOS13
中看到它仍然被调用了两次.
I update my didFinishLaunchingWithOptions
and I can see in iOS13
it is still called twice.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
guard #available(iOS 12, *) else { return true }
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = HomeViewController()
window.makeKeyAndVisible()
self.window = window
return true
}
推荐答案
您确实需要复制代码,但需要确保它仅在正确的系统上运行.在 iOS 13 中,您不希望该应用程序委托 didFinishLaunching
主体代码运行,因此使用可用性检查来阻止它.同样,使用可用性从 iOS 12 中隐藏窗口场景内容.
You do need to duplicate the code but you need to make sure it runs only on the correct system. In iOS 13 you don’t want that application delegate didFinishLaunching
body code to run, so use an availability check to prevent it.
In the same way, use availability to hide the window scene stuff from iOS 12.
以下是在 iOS 12 和 iOS 13 上都能正确运行的解决方案的基本草图:
Here's the basic sketch of a solution that runs correctly on both iOS 12 and iOS 13:
import UIKit
@UIApplicationMain
class AppDelegate : UIResponder, UIApplicationDelegate {
var window : UIWindow?
func application(_ application: UIApplication,
didFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey : Any]?)
-> Bool {
if #available(iOS 13, *) {
// do only pure app launch stuff, not interface stuff
} else {
self.window = UIWindow()
let vc = ViewController()
self.window!.rootViewController = vc
self.window!.makeKeyAndVisible()
self.window!.backgroundColor = .red
}
return true
}
}
SceneDelegate.swift
import UIKit
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window : UIWindow?
func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
self.window = UIWindow(windowScene: windowScene)
let vc = ViewController()
self.window!.rootViewController = vc
self.window!.makeKeyAndVisible()
self.window!.backgroundColor = .red
}
}
}
ViewController.swift
import UIKit
class ViewController : UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("view did load")
self.view.backgroundColor = .green
}
}
请注意,处理其他重复项(例如应用程序激活)要简单得多,因为如果您支持窗口场景,则不会在 iOS 12 上调用应用程序委托方法.因此问题仅限于这种情况,即 where您可以在启动时执行窗口/根视图控制器操作(例如,没有故事板).
Note that dealing with other duplicates, such as the application activating, is much simpler because if you support window scenes the application delegate method won't be called on iOS 12. So the problem is confined to this one situation, namely where you have window / root view controller manipulations to perform at launch (e.g. no storyboard).
这篇关于支持 iOS 12 和 13 时的 AppDelegate 和 SceneDelegate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!