设置 rootViewController iOS 13
Set rootViewController iOS 13
升级后 Xcode 我的应用程序的关键部分已停止工作。
当我的应用程序启动时,我 运行 一个函数来检查布尔标志并设置正确的 rootViewController。
但是我一直用来设置它的代码现在已经停止工作
class func setLoginAsInitialViewContoller(window:UIWindow) {
print("SET LOGIN")
let storyboard = UIStoryboard(name: "Login", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "LoginViewController")
controller.modalPresentationStyle = .overFullScreen
window.rootViewController = controller
window.makeKeyAndVisible()
}
特别是当应用程序获取倒数第二行时 window.rootViewController = controller
它崩溃并出现 libc++abi.dylib: terminating with uncaught exception of type NSException
错误。
上面的函数在一个名为 Utilities.swift
的 class 中,我正在从我的 AppDelegate.swift
中调用该函数,如下所示:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var storyboard: UIStoryboard? = nil
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.isIdleTimerDisabled = true
Utilities.decideInitialViewController(window: self.window!)
return true
}
非常感谢任何关于如何设置根控制器的解决方案或修复。
谢谢!
这是因为 AppDelegate 不再有 window
属性。
现在您必须使用 SceneDelegate 的 scene(_:willConnectTo:options:)
方法来更改根视图控制器。
如本例所示:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let scene = (scene as? UIWindowScene) else { return }
// Instantiate UIWindow with scene
let window = UIWindow(windowScene: scene)
// Assign window to SceneDelegate window property
self.window = window
// Set initial view controller from Main storyboard as root view controller of UIWindow
self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
// Present window to screen
self.window?.makeKeyAndVisible()
}
它在您项目的 SceneDelegate.swift 文件中可用
它将有委托方法:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions)
例子
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
self.window = UIWindow(windowScene: windowScene)
let initialViewController =
storyboard.instantiateViewController(withIdentifier: "FirstViewController")
self.window!.rootViewController = initialViewController
self.window!.makeKeyAndVisible()
}
}
在viewDidAppear中你可以设置root:-
override func viewDidAppear(_ animated: Bool) {
print(self.view.window)
let vc = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as? SecondViewController
self.view.window?.rootViewController = vc
}
- 如果要使用
ScenceDelegate
。在 scene(_:willConnectTo:options:
中创建一个新的 UIWindow,设置 window 的 rootViewController
并使此 window 成为 key
window.
- 如果不想用
ScenceDelegate
,可以尝试去掉by following this。
对于希望创建几个扩展来更改根视图控制器并且需要支持两种委托类型(UISceneDelegate 和 AppDelegate)的任何人,这里有两个:
extension UIViewController {
var appDelegate: AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
var sceneDelegate: SceneDelegate? {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let delegate = windowScene.delegate as? SceneDelegate else { return nil }
return delegate
}
}
如果您需要扩展以从具有 iOS12 和 iOS13 的 ViewController 到达 UIWindow 支持:
extension UIViewController {
var window: UIWindow? {
if #available(iOS 13, *) {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let delegate = windowScene.delegate as? SceneDelegate, let window = delegate.window else { return nil }
return window
}
guard let delegate = UIApplication.shared.delegate as? AppDelegate, let window = delegate.window else { return nil }
return window
}
}
升级后 Xcode 我的应用程序的关键部分已停止工作。
当我的应用程序启动时,我 运行 一个函数来检查布尔标志并设置正确的 rootViewController。
但是我一直用来设置它的代码现在已经停止工作
class func setLoginAsInitialViewContoller(window:UIWindow) {
print("SET LOGIN")
let storyboard = UIStoryboard(name: "Login", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "LoginViewController")
controller.modalPresentationStyle = .overFullScreen
window.rootViewController = controller
window.makeKeyAndVisible()
}
特别是当应用程序获取倒数第二行时 window.rootViewController = controller
它崩溃并出现 libc++abi.dylib: terminating with uncaught exception of type NSException
错误。
上面的函数在一个名为 Utilities.swift
的 class 中,我正在从我的 AppDelegate.swift
中调用该函数,如下所示:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var storyboard: UIStoryboard? = nil
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.isIdleTimerDisabled = true
Utilities.decideInitialViewController(window: self.window!)
return true
}
非常感谢任何关于如何设置根控制器的解决方案或修复。
谢谢!
这是因为 AppDelegate 不再有 window
属性。
现在您必须使用 SceneDelegate 的 scene(_:willConnectTo:options:)
方法来更改根视图控制器。
如本例所示:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let scene = (scene as? UIWindowScene) else { return }
// Instantiate UIWindow with scene
let window = UIWindow(windowScene: scene)
// Assign window to SceneDelegate window property
self.window = window
// Set initial view controller from Main storyboard as root view controller of UIWindow
self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
// Present window to screen
self.window?.makeKeyAndVisible()
}
它在您项目的 SceneDelegate.swift 文件中可用
它将有委托方法:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
例子
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
self.window = UIWindow(windowScene: windowScene)
let initialViewController =
storyboard.instantiateViewController(withIdentifier: "FirstViewController")
self.window!.rootViewController = initialViewController
self.window!.makeKeyAndVisible()
}
}
在viewDidAppear中你可以设置root:-
override func viewDidAppear(_ animated: Bool) {
print(self.view.window)
let vc = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as? SecondViewController
self.view.window?.rootViewController = vc
}
- 如果要使用
ScenceDelegate
。在scene(_:willConnectTo:options:
中创建一个新的 UIWindow,设置 window 的rootViewController
并使此 window 成为key
window. - 如果不想用
ScenceDelegate
,可以尝试去掉by following this。
对于希望创建几个扩展来更改根视图控制器并且需要支持两种委托类型(UISceneDelegate 和 AppDelegate)的任何人,这里有两个:
extension UIViewController {
var appDelegate: AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
var sceneDelegate: SceneDelegate? {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let delegate = windowScene.delegate as? SceneDelegate else { return nil }
return delegate
}
}
如果您需要扩展以从具有 iOS12 和 iOS13 的 ViewController 到达 UIWindow 支持:
extension UIViewController {
var window: UIWindow? {
if #available(iOS 13, *) {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let delegate = windowScene.delegate as? SceneDelegate, let window = delegate.window else { return nil }
return window
}
guard let delegate = UIApplication.shared.delegate as? AppDelegate, let window = delegate.window else { return nil }
return window
}
}