I have the following set up where a parent view holds a NavigationView
which displays a series of pages, A, B and C. On page C there is a button which hides the navigation view. I want to have it so that when the navigation view is shown again, it automatically navigates to page A, however I am unsure how to do this with SwiftUI, how can this be achieved?
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")
}
}
}
}
The setting here is not complicated. One thing is for any intermediate view, you have to set .isDetailLink(false)
. Otherwise, they will be kept during rewinding.
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")
}
}
}
}