I created an application in SwiftUI.
Views are structs, but I need to know the View Controller because it is needed for presenting some special alerts.
I see that in my project there are AppDelegate, and SceneDelegate.
I found this
let contentView = ContentView()
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
So I want to pass the View Controller reference to the other Views.
Is window.rootViewController the right value to pass and use?
The possible solution is to inject hosting view controller as environment key, so it can be available at any ContentView
internal hierarchy level.
Here is a demo. Tested with Xcode 12 / iOS 14.
struct RootViewControllerKey: EnvironmentKey {
static let defaultValue: UIViewController? = nil
}
extension EnvironmentValues {
var rootViewController: UIViewController? {
get { self[RootViewControllerKey.self] }
set { self[RootViewControllerKey.self] = newValue }
}
}
ContentView
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
let rootController = UIHostingController(rootView: AnyView(EmptyView()))
rootController.rootView = AnyView(contentView
.environment(\.rootViewController, rootController))
window.rootViewController = rootController
self.window = window
window.makeKeyAndVisible()
}
struct ContentView: View {
// can be used here as well
var body: some View {
TestSubView()
}
}
struct TestSubView: View {
@Environment(\.rootViewController) var viewController // for demo here!!
var body: some View {
Text("Demo")
.onAppear {
print(String(describing: self.viewController))
}
}
}
I do not know if this answer is a suitable solution, but it simply works for me, so be careful when using it.
class func getTopMostViewController() -> UIViewController? {
var topMostViewController = UIApplication.shared.keyWindow?.rootViewController
while let presentedViewController = topMostViewController?.presentedViewController {
topMostViewController = presentedViewController
}
return topMostViewController
}
the use the value like
let viewController=getTopMostViewController()
viewController.present(...
from StackOverflow answer:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.