1

Weird issue using new NavigationStack. When trying to push the DrinkView for the second time, it's pushed twice and the OrderFood gets view removed from the navigation.

The reason is @Published var openDrinks in the View Model. Is there is any way to solve this issue. Thanks.

import SwiftUI


struct ContentView: View {
    var body: some View {
        NavigationStack {
            VStack {
                
                Image(systemName: "globe")
                    .imageScale(.large)
                    .foregroundColor(.accentColor)
                NavigationLink("Hello", value: "Amr")
//                Text("Hello, world!")
            }
            .navigationTitle("Main")
            .padding()
            .navigationDestination(for: String.self) { value in
                OrderFood(viewModel: ViewModel())
            }
        }
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}




class ViewModel: ObservableObject {
    @Published var openDrinks: Bool = false
}

struct OrderFood: View {
    @ObservedObject var viewModel: ViewModel
//    @ObservedObject var viewModel = ViewModel()
    var body: some View {
        VStack {
            Text("Add Drink")
                .onTapGesture {
                    viewModel.openDrinks = true
                }
        }
        .navigationTitle("Order Food")
        .navigationDestination(isPresented: $viewModel.openDrinks) {
            DrinksView()
                .navigationTitle("Drinks")
        }
        .onAppear {
            viewModel.openDrinks = false
        }
    }
}

struct OrderFood_Previews: PreviewProvider {
    static var previews: some View {
        OrderFood(viewModel: ViewModel())
    }
}

import SwiftUI

struct DrinksView: View {
    
    var body: some View {
        NavigationLink("Ch") {
            Text("Hello, World!")
        }
    }
}

struct DrinksView_Previews: PreviewProvider {
    static var previews: some View {
        DrinksView()
    }
}

1 Answer 1

1

In ContentView, you use OrderFood(viewModel: ViewModel()), which means you create a new ViewModel every time you navigate to OrderFood.

Try this approach, where you have one source of truth, that you pass to the details view:

struct ContentView: View {
    @StateObject var viewModel = ViewModel()  // <-- here

    var body: some View {
        NavigationStack {
            VStack {
                Image(systemName: "globe")
                    .imageScale(.large)
                    .foregroundColor(.accentColor)
                NavigationLink("Hello", value: "Amr")
            }
            .navigationTitle("Main")
            .padding()
            .navigationDestination(for: String.self) { value in
                OrderFood(viewModel: viewModel) // <-- here
            }
        }
        
    }
}

Note, you could also use @EnvironmentObject in this case.

EDIT-1: using @EnvironmentObject to pass the viewModel around:

struct ContentView: View {
    @StateObject var viewModel = ViewModel()  // <-- here
    var body: some View {
        NavigationStack {
            VStack {
                Image(systemName: "globe")
                    .imageScale(.large)
                    .foregroundColor(.accentColor)
                NavigationLink("Hello", value: "Amr")
            }
            .navigationTitle("Main")
            .padding()
            .navigationDestination(for: String.self) { value in
                OrderFood() // <-- here
            }
        }.environmentObject(viewModel)  // <-- here
        
    }
}

struct OrderFood: View {
    @EnvironmentObject var viewModel: ViewModel  // <-- here
    
    var body: some View {
        VStack {
            Text("Add Drink")
                .onTapGesture {
                    viewModel.openDrinks = true
                }
        }
        .navigationTitle("Order Food")
        .navigationDestination(isPresented: $viewModel.openDrinks) {
            DrinksView().navigationTitle("Drinks")
        }
        .onAppear {
            viewModel.openDrinks = false
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.