Reputation: 3337
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?
Upvotes: 0
Views: 1069
Reputation: 3337
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:
Upvotes: 0
Reputation: 258345
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))
}
}
}
Upvotes: 1