[SOLVED] Implementing Button in side menu

Issue

can someone Help me with fixing this. I want this code to work such as when I click the Home button on the side menu, it should take me to the Main View("This is the Main View"). I have tried using presenting sheets, however, presenting sheet doesn’t look realistic. When the Home button is tapped, everything should disappear and only the Home Screen should come up with the side menu. I have tried writing up this code, however, I couldn’t make the home button work. The codes are as below:

import SwiftUI
import Foundation
import Combine


struct Home: View {
@State var showMenu = false
    @EnvironmentObject var userSettings: UserSettings
  
    var body: some View {
        
        let drag = DragGesture()
            .onEnded {
                if $0.translation.width < -100 {
                    withAnimation {
                        self.showMenu = false
                    }
                }
            }
        return NavigationView {
            
            GeometryReader {
            geometry in
               
            ZStack(alignment: .leading) {
                MainView(showMenu: self.$showMenu)
                .frame(width: geometry.size.width, height: geometry.size.height)
                .offset(x: self.showMenu ? geometry.size.width/2 : 0)
                .disabled(self.showMenu ? true : false)
                if self.showMenu {
                    MenuView()
                        .frame(width: geometry.size.width/2)
                        .transition(.move(edge: .leading))
                }
    }
            .gesture(drag)
        }
            .navigationBarTitle("Pay Data", displayMode: .inline)
       
            .navigationBarItems(leading: (Button(action: {
                withAnimation {
                    self.showMenu.toggle()
                }
            }){
                Image(systemName: "line.horizontal.3")
                    .imageScale(.large)
                
            }
                                         ))
    }
    }
}
struct MainView: View {
    @Binding var showMenu: Bool
        @EnvironmentObject var userSettings: UserSettings
    var body: some View {
        Text("This is Main View")
        
    }
}

struct Home_Previews: PreviewProvider {
    static var previews: some View {
        Home()
            .environmentObject(UserSettings())
       
    }
}

//This is the Menu View. The Home Button is located in this view.

import SwiftUI
import Combine
import Foundation


struct MenuView: View {
    @EnvironmentObject var userSettings: UserSettings
    @State var showMenu = false
    @State var Homevariable = false
    var body: some View {
        VStack(alignment: .leading) {
            
            Button(action: {
            
                UserDefaults.standard.set(false, forKey: "status")
                
               
            }) {
                (Text(Image(systemName: "rectangle.righthalf.inset.fill.arrow.right")) + (Text("Home")))
            }
              
           
        }
        .padding()
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(Color(red: 32/255, green: 32/255, blue: 32/255))
        .edgesIgnoringSafeArea(.all)
    }
 
}
struct MenuView_Previews: PreviewProvider {
    static var previews: some View {
        MenuView()
            .environmentObject(UserSettings())
       
    }
}

//This is the another view. I want the side Menu to appear on this as well, so when I press the Home button it takes me to the Main View("This is the Main View")

import SwiftUI

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

struct Calculation_Previews: PreviewProvider {
    static var previews: some View {
        Calculation()
    }
}

Solution

Here you go. You are basically rebuilding a navigation logic, so in MainView you have to switch between the screens and put the side menu over it:
(PS: you can do without GeometryReader)

enter image description here

struct ContentView: View {
    
    @State private var showMenu = false
    @State private var selected: SelectedScreen = .home
    
    var body: some View {
        
        NavigationView {
            ZStack {
                // show selected screen
                switch selected {
                case .home:
                    MainView()
                        .disabled(self.showMenu ? true : false)
                case .screen1:
                    OtherView(screen: 1)

                case .screen2:
                    OtherView(screen: 2)
                }
                
                // put menu over it
                if self.showMenu {
                    MenuView(showMenu: $showMenu, selected: $selected)
                        .transition(.move(edge: .leading))
                }
            }
            .navigationBarTitle("Pay Data", displayMode: .inline)
            
            // .navigationBarItems is deprecated, use .toolbar
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button {
                        withAnimation {
                            self.showMenu.toggle()
                        }
                    } label: {
                        Image(systemName: "line.horizontal.3")
                            .imageScale(.large)
                    }
                }
            }
        }
    }
}


enum SelectedScreen {
    case home
    case screen1
    case screen2
}


struct MenuView: View {
    
    @Binding var showMenu: Bool
    @Binding var selected: SelectedScreen
    
    var body: some View {
        HStack {
        VStack(alignment: .leading, spacing: 24) {
            Button {
                selected = .home
                showMenu = false
            } label: {
                Label("Home", systemImage: "rectangle.righthalf.inset.fill.arrow.right")
            }
            
            Button {
                selected = .screen1
                showMenu = false
           } label: {
                Label("Screen 1", systemImage: "1.circle")
            }
 
            Button {
                selected = .screen2
                showMenu = false
            } label: {
                Label("Screen 2", systemImage: "2.circle")
            }
        }
        .padding()
        .frame(maxHeight: .infinity)
        .background(Color(red: 32/255, green: 32/255, blue: 32/255))
            
            Spacer()
    }
    }
}

struct MainView: View {
    var body: some View {
        Text("This is Main View")
            .font(.largeTitle)
    }
}

struct OtherView: View {
    let screen: Int
    var body: some View {
        Text("Other View: Screen \(screen)")
            .font(.largeTitle)
    }
}

Answered By – ChrisR

Answer Checked By – Candace Johnson (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published.