简体   繁体   中英

How to navigate from side menu in SwiftUI to new view

I am working on app which has home view with navigation and side menu. Side menu has 2 levels menu ie each menu entries has sub menu(s). Whenever user click on any side sub-menu, app should display new view but i am unable to achieve this behavior. I tried Navigation view in sub-menu but then sub-menu is broken, i also tried to navigateTo but it also did not work.

This is home view which has attached side menu -

struct HomePageView: View {
    @State var size = UIScreen.main.bounds.width / 1.6
    
    var body: some View {
       GeometryReader{ geometry in
            NavigationView{
                VStack{
                    ScrollView (.vertical, showsIndicators: true) {
                        anotherView()
                        HStack{
                            Spacer(minLength: 0)
                        }
                    }.frame(width: geometry.size.width)
                }
                .background(Image("background").resizable().scaledToFill().clipped())
                .animation(.spring()).background(Color.lairBackgroundGray)
                .navigationBarItems(leading: Button(action: {
                    self.size = 10
                }, label: {
                    Image("menu")
                        .resizable()
                        .frame(width: 30, height: 30)
                }).foregroundColor(.appHeadingColor), trailing:
                    Button(action: {
                        withAnimation {
                            print("profile is pressed")
                        }
                    }) {
                        HStack {
                            NavigationLink(destination: ProfileView()) {
                                LinearGradient.lairHorizontalDark
                                    .frame(width: 30, height: 30)
                                    .mask(
                                        Image(systemName: "person.crop.circle")
                                            .resizable()
                                            .scaledToFit()
                                )
                            }
                        }
                    }
                ).navigationBarTitle("Home", displayMode: .inline)
                 .animation(.spring())
                }.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
            HStack{
                menu(size: self.$size)  // --> Side menu
                    .cornerRadius(20)
                    .padding(.leading, -self.size)
                    .offset(x: -self.size)
                Spacer().background(Color.lairBackgroundGray)
            }.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
            .animation(.spring())
           }
    }
}

Below is side menu view, it is created based on State variable -

struct menu : View {
    @Binding var size : CGFloat
    @State var logout: Bool = false
    @State private var didSubMenuPressed: Bool = false
    
    @State var sideMenuEntries = [
        SideMenuData(index: 0, imageName: "info.circle",
                     menuText: "Info",
                     subMenu: ["Info1", "Info2", "Info3", "Info4"],
                     expand: false),
        SideMenuData(index: 1, imageName: "doc.on.doc",
                     menuText: "Documents",
                     subMenu: ["Documents1", "Documents2"],
                     expand: false)
    ]
    
    var body : some View{
        VStack (alignment: .leading){
            HStack{
                Spacer()
                Button(action: {
                    self.size =  UIScreen.main.bounds.width / 1.6
                }) {
                    Image("close").resizable()
                        .frame(width: 15, height: 15)
                        .padding()
                }
                .foregroundColor(.white)
                .clipShape(Circle())
            }
            ForEach (sideMenuEntries.indices) { index in
                VStack (alignment: .leading, spacing: 0, content: {
                    HStack{
                        Image(self.sideMenuEntries[index].imageName).resizable().frame(width: 25, height: 25)
                            .foregroundColor(.white)
                        Text(self.sideMenuEntries[index].menuText).fontWeight(.heavy).foregroundColor(.white)
                        if self.sideMenuEntries[index].subMenu.count > 1 {
                            Image(systemName: self.sideMenuEntries[index].expand ? "chevron.compact.up" : "chevron.compact.down")
                                .resizable()
                                .frame(width: 10, height: 10)
                                .foregroundColor(.white)
                        }
                        
                        Image("logout-1").resizable().frame(width: 25, height: 25)//.padding(.leading, 5)
                            .foregroundColor(.white)
                        Text(self.sideMenuEntries[index].menuText).fontWeight(.heavy).foregroundColor(.white)
                        if self.logout {
                            //
                        }
                        
                    }
                    .contentShape(Rectangle())
                    .onTapGesture {
                        self.sideMenuEntries[index].expand.toggle()
                    }
                    if self.sideMenuEntries[index].expand {
                        VStack (alignment: .leading){
                            ForEach (self.sideMenuEntries[index].subMenu.indices) { index1 in
                                Button(action: {
                                    print("\(self.sideMenuEntries[index].subMenu[index1]) is pressed")
                                    self.size =  UIScreen.main.bounds.width / 1.6
                                    self.didSubMenuPressed.toggle()
                                }){
                                    Text(self.sideMenuEntries[index].subMenu[index1])
                                        .foregroundColor(.white)
                                }
                                .padding([.top, .bottom], 7)
                            }
                        }
                        .padding(.top, 14)
                        .padding(.leading, 34)
                    }
                })
            }
            Spacer()
        }
        .padding(.leading, 40)
        .frame(width: UIScreen.main.bounds.width / 1.3)
        .background(LinearGradient(
            gradient: Gradient(
                colors: [.buttonGradientStartColor, .buttonGradientEndColor]),
            startPoint: .top,
            endPoint: .bottom))
        // if u want to change swipe menu background color
    }
}

I found a way to achieve this behavior, create State var in HomePageview and Binding var in menu and that resolved my problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM