0

I have a screen with a button that, when pressed, displays a subview with a new set of buttons. If I click any button in the subview, it should hide the subview and take me to the next view. The strange thing is that I can remove the view with a binding variable, but it does not move to the next screen.

struct CartView: View {
@State var store : Store = Store()
@State private var pushed: Bool = false
@State var notLoggedIn = false
@State var showDeliveryView : Bool = false
@State var showScheduleView : Bool = false
@StateObject var cartVM = CartViewModel()
var body: some View{
    
        ZStack(alignment:.center){
            VStack{
       
                VStack{
                    Button.init(action: {
                        if  AppSettings.shared.getUserID() != ""{
                            self.pushed.toggle()
                            withAnimation{
                                self.showDeliveryView.toggle()
                            }
                        }else{
                            self.notLoggedIn = true
                        }
                    }
                    , label: {
                        Text("CHECKOUT")
                            .font(.headline)
                            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 40)
                            .foregroundColor(.white)
                            .background(Color.theme.appColor)
                            .font(.title2)
                    })


                    .cornerRadius(4)
                    .padding([.leading, .trailing, .bottom], 10)


                } 
                .padding().ignoresSafeArea()
            }
            .navigationBarTitle("Cart")
            
            if self.showDeliveryView {
                    GeometryReader{ geometry in
                        VStack{
                            Spacer()
                            DeliveryTypeView(store:store, pushStackClear : $showDeliveryView,isCartActive: $pushed)
                            .background(Color.white)
                        }
                    }.transition(.move(edge: .bottom))
                    .background(
                        Color.black.opacity(0.65)
                            .edgesIgnoringSafeArea(.all)
                            .onTapGesture{
                                withAnimation{
                                    self.showDeliveryView.toggle()
                                }
                            }
                    )


            }
        }


    }

}

DeliveryTypeView

struct DeliveryTypeView: View {
@State var store : Store = Store()
@State private var showinfoScreen = false
@Binding var pushStackClear : Bool
@Binding  var isCartActive : Bool
var body: some View {
    ZStack{

    VStack(alignment: .leading){
        Text("Choose Service Method")
            .font(.title2)
            .fontWeight(.bold)
        Divider()

            VStack(alignment : .leading){
                NavigationLink(destination: CustomerInfoFormView( isCartActive: $isCartActive,tappedStore: store), isActive : $showinfoScreen){
                }

                Button.init(action: {
                    pushStackClear.toggle()
                    self.showinfoScreen.toggle()
                }
                            , label: {
                    Text("CHECKOUT")
                        .font(.headline)
                        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 40)
                        .foregroundColor(.white)
                        .background(Color.theme.appColor)
                        .font(.title2)
                })


                HStack{
                    Image.init(systemName: "car")
                        .font(.title2)
                    Text("Deliver to Me by Shop")
                        .font(.title2)
                        .padding()
                        .onTapGesture {
                        self.showinfoScreen.toggle()
                    }

                }



                Divider()
                HStack{
                    Image.init(systemName: "building")
                        .font(.title2)
                    Text("I will Pickup from Shop")
                        .font(.title2)
                        .padding()
                }.onTapGesture {

                    self.showinfoScreen.toggle()
                }

            }

    }
    }.padding()
}
 }

Really appreciate your help.

Mac_Play
  • 302
  • 4
  • 21
  • Change `@State private var showinfoScreen = false` in `DeliveryTypeView` to a binding `@Binding var showinfoScreen: Bool` then move the `NavigationLink` into the `CartView` – cedricbahirwe Jan 10 '22 at 11:48
  • The problem is that when you are setting `pushStackClear` to `false`, `DeliveryTypeView` is removed from the view hierarchy (or something like that), so setting `showinfoScreen` to `true` does not push the `NavigationLink` because it has been just removed from the view hierarchy. – cedricbahirwe Jan 10 '22 at 11:54
  • Your condition says `if self.showDeliveryView {` then show the `DeliveryTypeView` (which contains the `NavigationLink`), so if `DeliveryTypeView` is hidden completely from the view hierarchy, you can not toggle the `NavigationLink` inside it‍♂️ – cedricbahirwe Jan 10 '22 at 11:55
  • @cedricbahirwe Ok. which could be the best place to hide the deliverytype view and move to a new screen? I have tried to remove the view in disappear method of deliverytype view and it works. But the problem once it moved to the next screen, it pops back immediately. – Mac_Play Jan 10 '22 at 12:02
  • what could be the best way to achieve this? – Mac_Play Jan 10 '22 at 12:10
  • There may be many solutions to this..., checkout one of them below – cedricbahirwe Jan 11 '22 at 13:03

1 Answers1

1
  1. Move the NavigationLink into CartView, so that CustomerInfoFormView presentation won't be tied to the presence of DeliveryTypeView
  2. Create/Adjust the binding

The code would look like this

CartView

struct CartView: View {
    @State var store : Store = Store()
    @State private var pushed: Bool = false
    @State var notLoggedIn = false
    @State var showDeliveryView : Bool = false
    @State var showScheduleView : Bool = false
    @State var showinfoScreen : Bool = false
    @StateObject var cartVM = CartViewModel()
    var body: some View{
        
        ZStack(alignment:.center){
            VStack{
                
                VStack{
                    Button.init(action: {
                        if  AppSettings.shared.getUserID() != ""{
                            self.pushed.toggle()
                            withAnimation{
                                self.showDeliveryView.toggle()
                            }
                        }else{
                            self.notLoggedIn = true
                        }
                    }
                                , label: {
                        Text("CHECKOUT")
                            .font(.headline)
                            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 40)
                            .foregroundColor(.white)
                            .background(Color.theme.appColor)
                            .font(.title2)
                    })
                    
                    
                        .cornerRadius(4)
                        .padding([.leading, .trailing, .bottom], 10)
                    
                    
                }
                .padding().ignoresSafeArea()
            }
            .navigationBarTitle("Cart")
            
            NavigationLink(destination: CustomerInfoFormView( isCartActive: $pushed,tappedStore: store), isActive : $showinfoScreen){
            }
            
            
            if self.showDeliveryView {
                GeometryReader{ geometry in
                    VStack{
                        Spacer()
                        DeliveryTypeView(store:store, showinfoScreen: $showinfoScreen, pushStackClear : $showDeliveryView,isCartActive: $pushed)
                            .background(Color.white)
                    }
                }.transition(.move(edge: .bottom))
                    .background(
                        Color.black.opacity(0.65)
                            .edgesIgnoringSafeArea(.all)
                            .onTapGesture{
                                withAnimation{
                                    self.showDeliveryView.toggle()
                                }
                            }
                    )
                
                
            }
        }
        
        
    }
    
}

DeliveryTypeView

struct DeliveryTypeView: View {
    @State var store : Store = Store()
    @Binding var showinfoScreen: Bool
    @Binding var pushStackClear : Bool
    @Binding  var isCartActive : Bool
    var body: some View {
        ZStack{
            
            VStack(alignment: .leading){
                Text("Choose Service Method")
                    .font(.title2)
                    .fontWeight(.bold)
                Divider()
                
                VStack(alignment : .leading){
                    
                    Button.init(action: {
                        pushStackClear.toggle()
                        self.showinfoScreen.toggle()
                    }
                                , label: {
                        Text("CHECKOUT")
                            .font(.headline)
                            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 40)
                            .foregroundColor(.white)
                            .background(Color.theme.appColor)
                            .font(.title2)
                    })
                    
                    
                    HStack{
                        Image.init(systemName: "car")
                            .font(.title2)
                        Text("Deliver to Me by Shop")
                            .font(.title2)
                            .padding()
                            .onTapGesture {
                                self.showinfoScreen.toggle()
                            }
                        
                    }
                    
                    
                    
                    Divider()
                    HStack{
                        Image.init(systemName: "building")
                            .font(.title2)
                        Text("I will Pickup from Shop")
                            .font(.title2)
                            .padding()
                    }.onTapGesture {
                        
                        self.showinfoScreen.toggle()
                    }
                    
                }
                
            }
        }.padding()
    }
}
cedricbahirwe
  • 1,274
  • 4
  • 15