首页 > 解决方案 > SwiftUI 导航到 NavigationView 堆栈的底部

问题描述

我有以下设置,其中父视图包含NavigationView显示一系列页面 A、B 和 C。在页面 C 上有一个隐藏导航视图的按钮。我想拥有它,以便当再次显示导航视图时,它会自动导航到页面 A,但是我不确定如何使用 SwiftUI 执行此操作,如何实现?

struct ParentView: View {
    @State var showNavigation:Bool = true
    var body: some View {
        ZStack {
            Button(action: {
                self.showNavigation = true
            }) {
                Text("Show navigation")
            }
            NavigationView {
                NavigationLink(destination: ChildA(showNavigation: $showNavigation)) {
                    Text("Go to A")
                }
            }.opacity(showNavigation ? 1.0 : 0.0)
        }
    }
}

struct ChildA: View {
    @Binding var showNavigation:Bool

    var body: some View {
        VStack {
            Text("A")
            NavigationLink(destination: ChildB(showNavigation: $showNavigation)) {
                           Text("Go to B")
                       }
        }
    }
}

struct ChildB: View {
    @Binding var showNavigation:Bool

    var body: some View {
        VStack {
            Text("B")
            NavigationLink(destination: ChildC(showNavigation: $showNavigation)) {
                           Text("Go to C")
                       }
        }
    }
}

struct ChildC: View {
    @Binding var showNavigation:Bool

    var body: some View {
        VStack {
            Text("C")
            Button(action: {
                self.showNavigation = false
            }) {
                Text("Hide Navigation")
            }
        }
    }
}

流动

标签: swiftuiresetnavigationview

解决方案


这里的设置并不复杂。一件事是对于任何中间视图,您必须设置.isDetailLink(false). 否则,它们将在倒带期间保留。

struct ParentView: View {
    @State var showNavigation:Bool = true
    @State var isActive:Bool = true

    var body: some View {
        ZStack {
            Button(action: {
                self.showNavigation = true
            }) {
            Text("Show navigation")
        }
        NavigationView {
            NavigationLink.init(
                destination: ChildA(showNavigation: $showNavigation, isActive: $isActive), 
                isActive: $isActive) {
                    Text("Go to A")
                }
            }.opacity(showNavigation ? 1.0 : 0.0)
        }
    }
}

struct ChildA: View {
    @Binding var showNavigation:Bool
    @Binding var isActive:Bool
    @State var isNextActive:Bool = false
    var body: some View {
        VStack {
            Text("A")
            NavigationLink(
                destination: ChildB(showNavigation: $showNavigation, isActive: $isNextActive), 
                isActive: $isNextActive) {
                     Text("Go to B")
                }.isDetailLink(false)
            }.onReceive(Just(isNextActive)) { isNextActive in
                if isNextActive == false && (!self.showNavigation) {

                    self.isActive = false
                }
            }
        }
    }
}

struct ChildB: View {
    @Binding var showNavigation:Bool
    @Binding var isActive:Bool
    @State var isNextActive:Bool = false

    var body: some View {
        VStack {
            Text("B")
            NavigationLink(destination: ChildC(showNavigation: $showNavigation, isActive: $isNextActive), isActive: $isNextActive) {
                Text("Go to C")
            }.isDetailLink(false)
        }.onReceive(Just(isNextActive)) { isNextActive in
            if isNextActive == false && (!self.showNavigation) {
                DispatchQueue.main.async {
                    self.isActive = false
                }
            }
        }             
    }
}

struct ChildC: View {
    @Binding var showNavigation:Bool
    @Binding var isActive:Bool
    var body: some View {
        VStack {
            Text("C")
            Button(action: {
                self.showNavigation = false
                self.isActive = false
            }) {
                Text("Hide Navigation")
            }
        }
    }
}

推荐阅读