对于这个答案的一个小更新,你还可以通过以下方式实现:
你可以创建一个路由器(Router)类
首先,创建一个扩展UIApplication
import Foundation
import UIKit
extension UIApplication {
var keyWindow: UIWindow? {
return UIApplication.shared.connectedScenes
.filter { $0.activationState == .foregroundActive }
.first(where: { $0 is UIWindowScene })
.flatMap({ $0 as? UIWindowScene })?.windows
.first(where: \.isKeyWindow)
}
}
获取主窗口的方法
然后创建一个路由器(Router)类并添加以下方法:
import Foundation
import SwiftUI
final class Router {
public static func showMain(window: UIWindow? = nil) {
Router.setRootView(view: MainView(), window: window)
}
private static func setRootView<T: View>(view: T, window: UIWindow? = nil) {
if window != nil {
window?.rootViewController = UIHostingController(rootView: view)
UIView.transition(with: window!,
duration: 0.3,
options: .transitionCrossDissolve,
animations: nil,
completion: nil)
return
}else {
UIApplication.shared.keyWindow?.rootViewController = UIHostingController(rootView: view)
UIView.transition(with: UIApplication.shared.keyWindow!,
duration: 0.3,
options: .transitionCrossDissolve,
animations: nil,
completion: nil)
}
}
}
你现在可以从你代码中的任何位置调用它,例如从SceneDelegate中:
Router.showMain(window: window)
或者不使用 window 参数
Router.showMain() //if the window is nil it will go to the else statement and use UIApplication.keyWindow.
并且过渡将会有动画效果。
旧答案:
import Foundation
import UIKit
import SwiftUI
class Router {
class var window: UIWindow? {
if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
if let sceneDelegate = scene.delegate as? SceneDelegate {
let window = UIWindow(windowScene: scene)
sceneDelegate.window = window
window.makeKeyAndVisible()
return window
}
}
return nil
}
static func showMain() {
window?.rootViewController = UIHostingController(rootView: ContentView())
}
}
使用方法:
Router.showMain()
使用这个功能,你可以在任何时候决定哪个窗口是你的根窗口。