Home > other >  Conditional Navigation in SwiftUI from another view
Conditional Navigation in SwiftUI from another view

Time:11-25

I have created separate views for buttons and textField. When I tap on the button I should check for textField is empty/not and if it is not empty, I should navigate to the next page. Here I got struck with managing navigationDestination based on the scenario.

class UserProgress: ObservableObject {
    @Published var value = ""
    @Published var flag = false
 }

struct ButtonView: View {
    @StateObject var progress = UserProgress()
    
    var body: some View {
        Button("Button title") {
            print("Button tapped! \(progress.value.count)")
            progress.flag = true
        }
    }
}

struct TextView: View {
    
    @Binding var textValue: String
    @ObservedObject var progress: UserProgress
    
    var body: some View {
        VStack {
            TextField("Hello", text: $textValue)
                .onChange(of: textValue) {
                    progress.value = $0
            }
        }
    }
}

struct mainViewApp: View {
    @StateObject var progress = UserProgress()
    @State var readyToNavigate: Bool = false
    @State var text1Value = ""
    @State var text2Value = ""
    
    var body: some View {
        NavigationStack {
            ZStack {
                VStack {
                    VStack {
                        Text("Your value is \(progress.value)")
                        
                        TextView(textValue: $text1Value, progress: progress)
                        if (progress.flag && text1Value.isEmpty) {
                            Text("ERROR1")
                        }
                        TextView(textValue: $text2Value, progress: progress)
                        if (progress.flag && text2Value.isEmpty) {
                            Text("ERROR2")
                        }
                        ButtonView(progress: progress)
                    }
                }
            }
            .padding()
            .navigationBarTitle("Main Menu", displayMode: .inline)
            .navigationDestination(isPresented: $readyToNavigate) {
                Text("Hello test2")
            }
            
            .toolbarColorScheme(.dark, for: .navigationBar)
            .toolbarBackground(
                Color.black,
                for: .navigationBar)
            .toolbarBackground(.visible, for: .navigationBar)
        }
    }
}

struct test_Previews: PreviewProvider {
    static var previews: some View {
        mainViewApp()
    }
}

here I tried managing its observables but couldn't able to update the state value of readyToNavigate inside the condition where I Am checking. Advance thanks

CodePudding user response:

This is a better way to handle the viewmodel

 import Foundation
        import SwiftUI

        class UserProgress: ObservableObject {
            @Published var canNavigate = false
            @Published var text1Value = ""
            @Published var text2Value = ""
            
            
            func fieldsEmpty() -> Bool {
                return !text1Value.isEmpty && !text2Value.isEmpty
            }
        }

        struct ButtonView: View {
            @ObservedObject var progress: UserProgress
            
            var body: some View {
                Button("Button title") {
                    print("Button tapped!")
                    if (progress.fieldsEmpty()) {
                        progress.canNavigate = true
                    }
                }
            }
        }

        struct TextView: View {
            
            @Binding var textValue: String
            
            var body: some View {
                VStack {
                    TextField("Hello", text: $textValue)
                }
            }
        }

        struct mainViewApp: View {
            @StateObject var progress = UserProgress()
            
            var body: some View {
                NavigationStack {
                    ZStack {
                        VStack {
                            VStack {
                                Text("Your value is \(progress.text1Value)")
                                
                                TextView(textValue: $progress.text1Value)
                                
                                TextView(textValue: $progress.text2Value)
                                
                                if(!progress.fieldsEmpty()) {
                                    Text("Please fill boths textfields")
                                        .foregroundColor(.red)
                                }
                                
                                ButtonView(progress: progress)
                            }
                        }
                    }
                    .padding()
                    .navigationBarTitle("Main Menu", displayMode: .inline)
                    .navigationDestination(isPresented: $progress.canNavigate) {
                        Text("Hello test2")
                    }
                    
                    .toolbarColorScheme(.dark, for: .navigationBar)
                    .toolbarBackground(
                        Color.black,
                        for: .navigationBar)
                    .toolbarBackground(.visible, for: .navigationBar)
                }
            }
        }

enter image description here

  • Related