Search code examples
iosswiftuinavigationview

Disable SwiftUI NavigationView Swipe to Pop feature


I am using SwiftUI NavigationView to navigate to three pages. Navigation works fine, I can go to my desired pages and go back to the previous page using the back button.

My problem is whenever i swipe from the leftmost part of the screen, it pops my current screen.

Whenever I drag from the leftmost part of the screen, my current screen also moves along showing the previous screen from the stack then pops the said current screen.

Is there a way to disable this feature?

Page Two to One

Page One to Landing

ContentView.swift

import SwiftUI

struct ContentView: View {
    @State var destinationKey: String? = nil;

    var body: some View {
        NavigationView{
            VStack{
                Text("Hello, world! Landing Page")
                    .padding()
            
                Button(action: {
                    destinationKey = "pageOne"
                }) {
                    Text("Go To Page One")
                        .padding()
                }
            
            }
            .background(
                NavigationLink(destination: PageOne(), tag: ("pageOne"), selection: $destinationKey){
                    EmptyView()
                }
            )
        }
        .navigationViewStyle(StackNavigationViewStyle())

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

PageOne.swift

import SwiftUI

struct PageOne: View {
    
    var body: some View {
        VStack{
            Text("Hello, World! Page One")
        
            NavigationLink(destination: PageTwo(), label: {
                Text("Go To Page Two")
                    .padding()
            
            })
        
        
        }
    }
}

struct PageOne_Previews: PreviewProvider {
    static var previews: some View {
        PageOne()
    }
}

PageTwo.swift

import SwiftUI

struct PageTwo: View {
    var body: some View {
        Text("Hello, World! Page Two")
    }
}

struct PageTwo_Previews: PreviewProvider {
    static var previews: some View {
        PageTwo()
    }
}

Solution

  • As of now, the only way to disable the swipe to dismiss is to disable the back button:

     .navigationBarBackButtonHidden(true)
    

    If you wish to still have a back button, you can create a custom one with:

    .navigationBarItems(leading: Button("Back"){self.presentationMode.wrappedValue.dismiss()})
    

    Note: this code is placed in the presenting view and remember to do

    @Environment(\.presentationMode) var presentationMode
    

    in your struct for iOS 14 and before, or if you are on iOS 15 you can simply do:

    @Environment(\.dismiss) var dismiss
    

    And simply call dismiss() in your custom back button:

    .navigationBarItems(leading: Button("Back"){dismiss()})