【问题标题】:Multiple back buttons created when navigates to root screen in SwiftUI在 SwiftUI 中导航到根屏幕时创建多个后退按钮
【发布时间】:2023-01-26 20:36:36
【问题描述】:

假设我在 SwiftUI 中创建了 3 个屏幕,其中包含指向下一个屏幕的 NavigationLink。比如,第一个屏幕导航到第二个屏幕。第二个屏幕导航到第三个。第三个屏幕导航到第一个屏幕。在这种情况下,即使我只使用 NavigationView 一次(在第一个屏幕中)。当我从第三个屏幕导航到第一个屏幕时,我遇到了一个后退按钮。从那时起,当我开始导航时,它会不断增加。我试过使用.navigationBarBackButtonHidden(true)。它隐藏了它,但后退按钮占用的空间仍然存在。 我的代码与此类似:

struct FirstScreen: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: SecondScreen()) {
                    Text("Go to Second Screen")
                }
            }
        }
    }
}

struct SecondScreen: View {
    var body: some View {
        VStack {
            NavigationLink(destination: ThirdScreen()) {
                Text("Go to Third Screen")
            }
        }
    }
}

struct ThirdScreen: View {
    var body: some View {
        VStack {
            NavigationLink(destination: FirstScreen()) {
                Text("Go to First Screen")
            }
        }
    }
}

this is the image

【问题讨论】:

    标签: ios swiftui swiftui-navigationlink swiftui-navigationview


    【解决方案1】:

    您正在将 FirstScreen 推送到您的导航堆栈,但 FirstScreen 包含它自己的 NavigationView。如果您真的想继续将它们压入堆栈,请将 NavigationView 移到 FirstScreen 之外。

    struct ContentView: View {
        var body: some View {
            NavigationStack { // Use NavigationStack for iOS 16
                FirstScreen()
            }
        }
    }
    
    struct FirstScreen: View {
        var body: some View {
            VStack {
                NavigationLink(destination: SecondScreen()) {
                    Text("Go to Second Screen")
                }
            }
        }
    }
    

    如果您真的想从堆栈中弹出所有视图并返回到FirstScreen,您应该使用

    init(path: Binding<NavigationPath>, etc)
    

    这是一个简单的示例,将 path 向下传递到堆栈并将其重置为弹出回根...

    enum Screen {
        case two, three
    }
    
    struct ContentView: View {
        
        @State var path = NavigationPath()
    
        var body: some View {
            NavigationStack(path: $path) {
                VStack {
    
                    // value gets appended to path
                    NavigationLink("Go to Second Screen", value: Screen.two)
                }
    
                // Decides which screen to show for values in path
                .navigationDestination(for: Screen.self) { index in
                    switch index {
                    case .two:
                        SecondScreen(path: $path)
                    case .three:
                        ThirdScreen(path: $path)
                    }
                }
            }
        }
    }
    
    struct SecondScreen: View {
        @Binding var path: NavigationPath
        var body: some View {
            VStack {
                NavigationLink("Go to Third Screen", value: Screen.three)
            }
        }
    }
    
    struct ThirdScreen: View {
        @Binding var path: NavigationPath
        var body: some View {
            VStack {
                Button("Go to First Screen") {
    
                    // reset the path to pop to root
                    path = NavigationPath()
                }
            }
        }
    }
    

    【讨论】:

    • 我想采用这种方法 init(path: Binding<NavigationPath>, etc) 你能在我的上下文中详细说明吗?
    • 查看我更新的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    • 2011-08-10
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多