swift (2023)NavigationStack和NavigationDestination,正确使用NavigationPath

ikfrs5lh  于 2023-05-16  发布在  Swift
关注(0)|答案(1)|浏览(342)

我正在努力完成一个相对简单的任务。我想从根视图->捕获输入的中间视图->显示输入的最终视图->返回到根视图。
我提出的解决方案使用了新的NavigationPath和NavigationStack构造,部分来源于这篇堆栈溢出文章:A complex Navigation with NavigationPath in SwiftUI
我用我的视图(NAV_ITEMS)创建了一个枚举,然后创建了一个类型为NAV_ITEMS的路径,当我想转到下一个视图时,就推到该路径上。这种解决方案的缺点是我从根视图管理名为newRoomName的状态变量,并将其作为绑定传递给两个子视图,这似乎是错误的。

import SwiftUI

enum NAV_VIEWS {
    case AddRoomName, AddRoomSuccess, addHomeName, addHomeNameSuccess
}

struct NavPathTestView: View {
    
    @State var presentedViews = [NAV_VIEWS]()
    @State var newRoomName: String = ""

        var body: some View {
            NavigationStack(path: $presentedViews) {
                NavigationLink(value: NAV_VIEWS.AddRoomName) {
                    HStack {
                        Text("Add Room")
                    }.padding()
                        .foregroundColor(.white)
                        .background(Color.red)
                        .cornerRadius(40)
                }

                .navigationDestination(for: NAV_VIEWS.self) { i in
                    switch i {
                    case .AddRoomName:
                            RoomView(presentedViews: $presentedViews, newRoomName: $newRoomName)
                    case .AddRoomSuccess:
                            RoomSuccessView1(presentedViews: $presentedViews, newRoomName: $newRoomName)
                    case .addHomeName:
                        Text("add Home Name")
                    case .addHomeNameSuccess:
                        Text("Add Home Success")
                    }
                }
                .navigationTitle("Root Page")
            }
        }
}

struct RoomView: View {
      
    @Binding var presentedViews : [NAV_VIEWS]
    @Binding var newRoomName: String
    
    var body: some View {
        
        VStack() {
            
            Text("Add Room Name")
            Spacer()
            TextField("My new Room", text: $newRoomName)
            .padding()
            .textInputAutocapitalization(.words)
            .cornerRadius(20)
            .onSubmit {
                print("NewRoomName: \(newRoomName)")
            }
            Spacer()
            Button (action: {
                presentedViews.append(NAV_VIEWS.AddRoomSuccess)
            })
            {
                HStack {
                    Text("Go to Success")
                }.padding()
                    .foregroundColor(.white)
                    .background(Color.red)
                    .cornerRadius(40)
            }
        }
        
    }
}

struct RoomSuccessView1: View {
    
    @Binding var presentedViews : [NAV_VIEWS]
    @Binding var newRoomName: String
    
    var body: some View {
        
        
        VStack {
            Text("Room Success Page")
            Spacer()
            Text("The passed newRoomName: \(newRoomName)")
            Spacer()
            Button (action: {
                presentedViews.removeLast(presentedViews.count)
            })
            {
                HStack {
                    Text("Back To Root")
                }.padding()
                    .foregroundColor(.white)
                    .background(Color.red)
                    .cornerRadius(40)
            }
        }
    }
}

struct NavPathTestView_Previews: PreviewProvider {
    static var previews: some View {
        NavPathTestView()
    }
}

有没有更好的办法?在每个子视图上使用navigationDestination进行路由会导致路径问题和屏幕如何进入演示文稿的动画问题。
例如,如果我在每个子视图(child 1-> child 2)上使用navigationDestination,然后从child 2视图调用RootView()导航回root,它将返回,但下次打开child 1时,它将从屏幕左手滑入,与正常的从右侧滑入不同。

nmpmafwu

nmpmafwu1#

SwiftUINavigationStackNavigationPath使整个导航比以前更容易。您可以使用如下的NavigationPath来处理整个应用程序中的任何导航,仅使用Data Type。使用navigationDestination(for: )函数为不同的数据类型定义不同的目的地。

当我自己尝试NavigationStackNavigationPath时,我首先遇到了很多问题。整个互联网并没有给我提供一个坚实的深刻理解。这就是为什么我在Medium上写了一个article,并在GitHub上写了一个关于多级嵌套导航的示例项目。

阅读Medium上的文章并从GitHub运行项目

struct ContentView: View {
    @State var path: NavigationPath = .init()
    var body: some View {
        NavigationStack(path: $path.animation(.easeOut)) {
            VStack {
                Button(action: {
                    path.append(FoodItemListView.tag)
                }) {
                    MenuButton(label: "Yummy Foods 🍕")
                }
            
                Button(action: {
                    path.append(ClothItemListView.tag)
                }) {
                    MenuButton(label: "Fashionable Cloths 🛍️")
                }
            }.navigationTitle("SwiftUI Navigations")
            .padding(.horizontal, 20)
            .padding(.vertical, 15)
            .navigationDestination(for: String.self) { tag in
                if tag == FoodItemListView.tag {
                    FoodItemListView(path: $path)
                } else if tag == ClothItemListView.tag {
                    ClothItemListView(path: $path)
                }
            }.navigationDestination(for: FastFood.self) { foodItem in
                FoodItemDetailsView(foodItem: foodItem, path: $path)
            }.navigationDestination(for: Cloth.self) { clothItem in
                ClothItemDetailsView(clothItem: clothItem, path: $path)
            }
        }
    }
}

相关问题