I tried to use this method (see link attached) in a new Xcode 12 project as a way to create a login page for a SwiftUI app, but I had the Problem not knowing what to add to the main App struct. I'm still a beginner and tried adding ContentView().environmentObject(ViewRouter())
to the WindowGroup in the main app struct. Am I totally wrong or why doesn't Xcode build the view? Can somebody help?
Below the working code snippet:
import SwiftUI
import Foundation
import Combine
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: MotherView().environmentObject(ViewRouter()))
self.window = window
window.makeKeyAndVisible()
}
}
. . .
}
class ViewRouter: ObservableObject {
let objectWillChange = PassthroughSubject<ViewRouter,Never>()
var currentPage: String = "page1" {
didSet {
withAnimation() {
objectWillChange.send(self)
}
}
}
}
struct MotherView : View {
@EnvironmentObject var viewRouter: ViewRouter
var body: some View {
VStack {
if viewRouter.currentPage == "page1" {
ContentViewA()
} else if viewRouter.currentPage == "page2" {
ContentViewB()
.transition(.scale)
}
}
}
}
struct ContentViewA : View {
@EnvironmentObject var viewRouter: ViewRouter
var body: some View {
Button(action: {self.viewRouter.currentPage = "page2"}) {
Text("Login")
}
}
}
struct ContentViewB : View {
@EnvironmentObject var viewRouter: ViewRouter
var body: some View {
Button(action: {self.viewRouter.currentPage = "page1"}) {
Text("Logout")
}
}
}
Now I want to substitute the SceneDelegate in the Xcode 12 style, but the following doesn't work. Any idea why?
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
MotherView().environmentObject(ViewRouter())
}
}
}
Pls try next steps:
remove whole SceneDelegate class (in your case no need SceneDelegate class)
Modify your ViewRouter class like:
class ViewRouter: ObservableObject { @Published var currentPage: String = "page1" }