Change the root view of UIHostingController in SwiftUI
Declare an AppRootView, something like this:
struct AppRootView: View {
@ObservedObject private var auth: Auth
var body: some View {
Group {
if auth.token != nil {
MainTabbedView()
} else {
StartRegistrationView()
}
}
}
}
and then in SceneDelegate set it as the root view:
window.rootViewController = UIHostingController(rootView: AppRootView(auth: $auth))
You have to bind your view to your Auth() either by passing it in as I did above or by setting it on your environment. The beauty of SwiftUI is that as soon as the token is not nil, the view will redraw and your user will find them selves in MainTabbedView.
How do I change the root view with SwiftUI
You just display each view conditionally in a root view
var body: some View {
if isLoggedIn {
HomeView()
} else {
LoginView() {
}
}
What is equivalent to 'window.rootViewController' in WindowGroup - SwiftUI
With the help of comments and some tutorials, I reached out to the solution (Tested on iOS 15, Xcode 13.2.1):
Add the following code to the Main App Launcher.
struct MyApp: App {
@StateObject var appState = AppState.shared
var body: some Scene {
WindowGroup {
SplashScreenView().id(appState.environment)
}
}
}
And then I created the AppState class, which is the class that when changes I will change the window.
class AppState: ObservableObject {
static let shared = AppState()
@Published var environment = "Production"
}
And whenever I wanted to change the environment and do the same functionality of changing window in UIKit
, do the following :
AppState.shared.environment = "Pre-Production"
How to push a new root view using SwiftUI without NavigationLink?
Here is possible alternate approach of how to replace root view completely... using notifications
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
let loginRootViewNotification =
NSNotification.Name("loginRootViewNotification") // declare notification
private var observer: Any? // ... and observer
...
// in place of window creation ...
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
observer = NotificationCenter.default.addObserver(forName: loginRootViewNotification, object: nil, queue: nil, using: { _ in
let anotherRootView = AnotherRootView()
// create another view on notification and replace
window.rootViewController = UIHostingController(rootView: anotherRootView)
})
in your desired place post needed notification
Button(action: {
// launch new root view here
NotificationCenter.default.post(loginRootViewNotification)
}, label: {Text("Login")}).padding()
SwiftUI - How to access UIHostingController from SwiftUI
Here is a demo of possible approach - to use external configuration wrapper class to hold weak link to controller and inject it into SwiftUI view (as alternate it is also possible to make it ObservableObject
to combine with other global properties and logic).
Tested with Xcode 12.5 / iOS 14.5
class Configuration {
weak var hostingController: UIViewController? // << wraps reference
}
struct SwiftUIView: View {
let config: Configuration // << reference here
var body: some View {
Button("Demo") {
self.config.hostingController?.title = "New Title"
}
}
}
let configuration = ExtConfiguration()
let controller = UIHostingController(rootView: SwiftUIView(config: configuration))
// injects here, because `configuration` is a reference !!
configuration.hostingController = controller
controller.title = "title"
MyNavigationManager.present(controller)
Related Topics
Differencebetween Int and Int32 in Swift
Maximum Number of Peripherals on Corebluetooth
How to Enumerate All Nodes in a Sprite Kit Scene
Objective-C Wrapper for Cfunctionpointer to a Swift Closure
Play Audio from Internet Using Avaudioplayer
Perform Segue After Login Successful in Storyboards
Audiokit: Using the New Aksequencer with Any Variety of the Callback Instruments
Removing Duplicate Objects from Fetch Based on Object Parameter Updated Swift
Xcode: Could Not Locate Device Support Files
Programmatically Fire Button Click Event
Uitextview Is Not Scrolled to Top When Loaded
How to Deserialize an Escaped JSON String with Nsjsonserialization
Sprite Kit Pin Joints Appear to Have an Incorrect Anchor
How to Detect iOS 6 and All Minor Versions by User Agent
Thread Error in Ibaction While Overriding Prepareforsegue Function