iOS SwiftUI: pop or dismiss view programmatically
This example uses the new environment var documented in the Beta 5 Release Notes, which was using a value property. It was changed in a later beta to use a wrappedValue property. This example is now current for the GM version. This exact same concept works to dismiss Modal views presented with the .sheet modifier.
import SwiftUI
struct DetailView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var body: some View {
Button(
"Here is Detail View. Tap to go back.",
action: { self.presentationMode.wrappedValue.dismiss() }
)
}
}
struct RootView: View {
var body: some View {
VStack {
NavigationLink(destination: DetailView())
{ Text("I am Root. Tap for Detail View.") }
}
}
}
struct ContentView: View {
var body: some View {
NavigationView {
RootView()
}
}
}
Dismiss of SwiftUI Views one after the other programmatically does not work
Add .isDetailLink(false)
to each NavigationLink
in your views... and all works.
NavigationLink(
destination: View2(types: ["Exams"], presentView2: $presentView2),
isActive: $presentView2,
label: {
Text("View2")
}).isDetailLink(false)
...
NavigationLink("View3", destination: View3(presentView3: $presentView3), isActive: $presentView3)
.isDetailLink(false)
...
NavigationLink("View4", destination: View4(presentView4: $presentView4), isActive: $presentView4)
.isDetailLink(false)
How to dismiss a SwiftUI NavigationView from a parent view
Here is the solution:
struct SwiftUIView: View {
@State var isPresent = true
@State var isDismissed: Bool = false
var body: some View {
HStack {
Button(action: {
isDismissed = true
}) {
Text("Dismiss View")
} // assume this button is always visible
NavigationView {
VStack {
Text("This is the NavigationView")
NavigationLink {
ViewToDismiss(dismissView: $isDismissed)
} label: {
Text("Go to view I want to exit")
}
}
}
}
}
}
struct ViewToDismiss: View {
@Environment(\.dismiss) private var dismiss
@Binding var dismissView: Bool
var body: some View {
Text("This is the view I want to exit")
.onChange(of: dismissView,
perform:
( { newValue in
dismiss()
}))
}
}
How can I pop to the Root view using SwiftUI?
Setting the view modifier isDetailLink
to false
on a NavigationLink
is the key to getting pop-to-root to work. isDetailLink
is true
by default and is adaptive to the containing View. On iPad landscape for example, a Split view is separated and isDetailLink
ensures the destination view will be shown on the right-hand side. Setting isDetailLink
to false
consequently means that the destination view will always be pushed onto the navigation stack; thus can always be popped off.
Along with setting isDetailLink
to false
on NavigationLink
, pass the isActive
binding to each subsequent destination view. At last when you want to pop to the root view, set the value to false
and it will automatically pop everything off:
import SwiftUI
struct ContentView: View {
@State var isActive : Bool = false
var body: some View {
NavigationView {
NavigationLink(
destination: ContentView2(rootIsActive: self.$isActive),
isActive: self.$isActive
) {
Text("Hello, World!")
}
.isDetailLink(false)
.navigationBarTitle("Root")
}
}
}
struct ContentView2: View {
@Binding var rootIsActive : Bool
var body: some View {
NavigationLink(destination: ContentView3(shouldPopToRootView: self.$rootIsActive)) {
Text("Hello, World #2!")
}
.isDetailLink(false)
.navigationBarTitle("Two")
}
}
struct ContentView3: View {
@Binding var shouldPopToRootView : Bool
var body: some View {
VStack {
Text("Hello, World #3!")
Button (action: { self.shouldPopToRootView = false } ){
Text("Pop to root")
}
}.navigationBarTitle("Three")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Related Topics
Getting Device Orientation in Swift
Set Dimensions for Uiimagepickercontroller "Move and Scale" Cropbox
Multiple Uilabels Inside a Self Sizing Uitableviewcell
How to Hide a Navigation Bar from First Viewcontroller in Swift
How to Get the Font Name from an Otf or Ttf File
How to Use Autolayout to Set Constraints on My Uiscrollview
Nsoperation and Nsoperationqueue Working Thread VS Main Thread
Differencebetween Pan and Swipe in iOS
How to Show/Hide a Uibarbuttonitem
How to Use Namespaces in Swift
How to Use Avfoundation to Crop a Video
What Does Addchildviewcontroller Actually Do
Getting a Device Udid from .Mobileconfig
Type 'Viewcontroller' Does Not Conform to Protocol 'Uitableviewdatasource'
Creating a Reusable Uiview with Xib (And Loading from Storyboard)