I can't find a way to go to the ContentView from ViewB without showing a secound NavigationView
on top of the other NavigationView
.
struct ContentView: View {
var body: some View {
NavigationView{
VStack {
Text("Go to ViewA")
NavigationLink(destination: ViewA()) {Text("Go")}
}.navigationBarTitle("ContentView")
}
}
}
struct ViewA: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
VStack {
Text("Go to ViewB")
NavigationLink(destination: ViewB()) {Text("Go to B")}
Text("Go back")
Button(action: { self.presentationMode.wrappedValue.dismiss() }) {Text("Go to ContentView")}
}.navigationBarTitle("ViewA")
}
}
struct ViewB: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
VStack {
Text("Go Home")
NavigationLink(destination: ContentView()) {Text("Go")}
Text("Go back")
Button(action: { self.presentationMode.wrappedValue.dismiss() }) {Text("Go to ViewB")}
}.navigationBarTitle("ViewB")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
In the "old" Swift i could easily make an unwindSegue like
@IBAction func unwindToVCMain(segue:UIStoryboardSegue) { }
}
and easily call it like
performSegue(withIdentifier: "unwindToVcMain", sender: nil)
Connect a Triggering Object to the Exit Control In your storyboard, create an unwind segue by right-clicking a triggering object and dragging to the Exit control at the top of your view controller's scene.
SwiftUI's NavigationLink has a second initializer that has an isActive parameter, allowing us to read or write whether the navigation link is currently active. In practical terms, this means we can programmatically trigger the activation of a navigation link by setting whatever state it's watching to true.
First, embed your first view in a navigation controller.
Then you insert a navigation link to the next view. The NavigationLink has different initialisers.
Choose this one with the isActive
parameter:
It is a bit mind-bending at first, but the isActive
parameter in the NavigationLink
becomes true
when the link is clicked and the navigation moves to the next screen.
It creates an instance that presents a destination when active
If I pass a binding keeping track of the state of this property, if at any time in my subsequent chain of views I set it to false again, it will reset and return to the original screen! It is quite neat!!
See this short example in code:
struct ContentView: View {
@State private var isActive: Bool = false
var body: some View {
NavigationView {
NavigationLink(
destination: SecondView(isActive: $isActive),
isActive: $isActive,
label: {
Text("Go to second View")
})
.navigationTitle("MainView")
}
}
}
My second View:
struct SecondView: View {
@Binding var isActive: Bool
var body: some View {
NavigationLink("Go to Third View",destination: ThirdView(isActive: $isActive))
.navigationTitle("Second View")
}
}
And here the button to unwind, but it could be in any view.
Setting isActive = false
does some magic here!
struct ThirdView: View {
@Binding var isActive: Bool
var body: some View {
Button("Unwind!"){
isActive = false
}
.navigationTitle("Last View!")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With