swiftUI navigation doesn't work when @state object changes the value

135 Views Asked by At

I've created modular architecture and I want all my features will be separate modules.

I want navigation also handles independently, but I am facing a problem to handle it.

Let's assume I have LoginScreen, RegisterScreen, and ProfileScreen. I can easily import RegisterModule inside LoginModule and navigate from LoginScreen to RegisterScreen. But this is a wrong approach to have a dependency on each other.

That's why I am looking for another solution. I come up with the idea to handle it in one SwiftUI file, more specifically in the ContentView(the start view).

struct ContentView: View {
    @State private var shouldNavigateToIntro = false
    var viewModel = SplashDI.shared.splashDependencies()
    
    init() {
        viewModel.$shouldNavigate.sink { [self] shouldNavigate in
            DispatchQueue.main.async {
                self.shouldNavigateToIntro = shouldNavigate
                print(shouldNavigate)
            }
        }.store(in: &viewModel.bag)
    }
    
    var body: some View {
        NavigationStack { // Wrap the content with NavigationView
                if shouldNavigateToIntro {
                    IntroView()
                } else {
                    SplashView(viewModel: viewModel)
                }
        }
    }
}

viewmodel

public final class SplashViewModel: ObservableObject {
    
    @Published public var shouldNavigate: Bool = false
    @Published var configs: TMConfig?
    public var bag = Set<AnyCancellable>()

    private let useCase: SplashUseCaseInterface
    
    public init(useCase: SplashUseCaseInterface) {
        self.useCase = useCase
    }

    
    @MainActor func getConfigs() {
            Task {
                do {
                    self.configs = try await useCase.getConfigs()
                    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(5), execute: {
                        self.shouldNavigate = true
                    })
                } catch {
                    self.configs = nil
                    print("Errorrrr: \(error)")
                }
            }
        }
}

The idea is from ViewModel will get the changed value and navigate it. If you can see print(shouldNavigate) it 100% works by giving the right values (false at the beggining, true at the end)

but the problem is my IntroView() never being called. I don't know what is the real problem.

I want properly handle navigation to go right view and easly clear stack if I need.

Can someone look my code to tell me what is the reason if it's not working? Or if someone knows how to work with with SPM and swiftUI navigation just put link here.

Note: using UINavigationController solving my issue but I want to have only pure SwiftUI.

0

There are 0 best solutions below