20

I have navigated to a new view with NavigationLink and I want to pop back to where I was programatically. Is it yet possible in swiftUI? I know for the modal presentation we could use the .isPresented environment value but how about navigation?

jpyams
  • 4,030
  • 9
  • 41
  • 66
Congruent Tech. UG
  • 1,408
  • 2
  • 12
  • 21
  • 2
    Check this Tutorial https://ryanashcraft.me/swiftui-programmatic-navigation/ – Ketan Odedra Jul 15 '19 at 09:39
  • This a a duplicate question. See my answer to this question: https://stackoverflow.com/questions/56513568/ios-swiftui-pop-or-dismiss-view-programmatically/57279591#57279591 – Chuck H Aug 02 '19 at 22:45

4 Answers4

31

You can really simply create custom back button. Only two lines code

@Environment(\.presentationMode) var presentationMode
self.presentationMode.wrappedValue.dismiss()

Example:

import SwiftUI

struct FirstView: View {
    @State var showSecondView = false
    
    var body: some View {
        NavigationLink(destination: SecondView(),isActive : self.$showSecondView){
            Text("Push to Second View")
        }
    }
}


struct SecondView : View{
    @Environment(\.presentationMode) var presentationMode

    var body : some View {    
        Button(action:{ self.presentationMode.wrappedValue.dismiss() }){
            Text("Go Back")    
        }    
    }
}
Sapar Friday
  • 652
  • 8
  • 7
  • Can you go back from a NavigationLink? – Berry Blue Aug 11 '22 at 20:38
  • this is really helpful for someone is new in swiftUI navigation world – Daniel Wijono Aug 18 '22 at 10:22
  • Hi, would there be any possibility to do the same with any navigation views opened in the app ? I am having a custom navigation bar and whenever I am inside nevigation links the view doesn't change until I go all the way back to the parent view.. – SnK Feb 08 '23 at 14:38
14

Yes you can now programmatically pop a NavigationLink View using the following code:

import SwiftUI

struct MainViewer: View {
    @State var showView = false
    var body: some View {
        
        NavigationLink(destination: DestView(showView: self.$showView),
                       isActive: self.$showView) {
          Text("Push View")                
        }
   }
}


struct DestView: View {
    @Binding var showView: Bool
    var body: some View {
    
        Button(action: {self.showView = false}) {
            Text("Pop Screen")            
        }        
    }
}
Jan
  • 1,032
  • 11
  • 26
sachin jeph
  • 209
  • 2
  • 4
3

If you use:

@Environment(\.dismiss) var dismiss

… in the view that is your destination, then you can call:

dismiss()

… where you want from within that view.

Example:

import SwiftUI

struct MainView: View {

var body: some View {
    NavigationLink(destination: SecondView()){
            Text("Push to Destination View")
        }
    }
}


struct DestinationView : View{
    @Environment(\.dismiss)

     var body : some View {    
        Button(action:{ self.dismiss() }){
             Text("Go Back")    
         }    
     }
 }
Guenhwyvar
  • 31
  • 2
1

This has to be a bug currently. Apple provides the boilerplate code to allow the "Back" or 'pop' functionality built in to a navigation view 'DetailView'. My only guess is Apple is working out the kinks in fully implementing Combine within SwiftUI in the backend to implement 'push' and 'pop' type of actions. I can't imagine SwiftUI coming out of beta without this functionality more accessible than creating a Combine publisher to update state similar to what RyanAshcraft did above.

tomEngland
  • 103
  • 1
  • 7