支持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上调用应用程序委托方法.因此,问题仅限于这种情况,即您可以在启动时执行窗口/根视图控制器操作(例如,没有情节提要).
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屋!