Bernhard
Bernhard

Reputation: 883

Dismiss of SwiftUI Views one after the other programmatically does not work

I use Xcode 12.2 and iOS build target 14.1. I have the problem with my SwiftUI app that closing views that use NavigationLink one after the other does not work.

The problem occurs with the following Swift source code when I first navigate to View4, click on "Dismiss" and then click on "Dismiss" again on View3. The latter button click causes no action. To get the "Dismiss" button of View3 working again, I would have to go to View2 with the Back button and then switch back to View3.

I tried previously to use presentationMode.wrappedValue.dismiss(), however that did not work with fewer views.

minimal reproducible Example:

struct View1: View {
    @State var presentView2: Bool = false
    
    var body: some View {
        NavigationView {
            List {
                NavigationLink(
                    destination: View2(types: ["Exams"], presentView2: $presentView2),
                    isActive: $presentView2,
                    label: {
                        Text("View2")
                    })
            }.listStyle(InsetGroupedListStyle())
            .navigationTitle("View1")
        }
    }
}
struct View2: View {
    var types: [String]
    @State var presentView3: Bool = false
    @Binding var presentView2: Bool
    
    var body: some View {
        List {
            Section {
                NavigationLink("View3", destination: View3(presentView3: $presentView3), isActive: $presentView3)
            }
            
            Section {
                Button(action: {self.presentView2 = false}, label: {
                    Text("Dismiss")
                })
            }
        }
        .listStyle(InsetGroupedListStyle())
        .navigationTitle(LocalizedStringKey("View2"))
    }
}
struct View3: View {
    @Binding var presentView3: Bool
    @State var presentView4: Bool = false
    @State
    var isAddViewPresented: Bool = false
    var body: some View {
        List {
            Section {
                NavigationLink("View4", destination: View4(presentView4: $presentView4), isActive: $presentView4)
            }
            
            Button(action: {presentView3 = false}, label: {
                Text("Dismiss")
            })
        }
        .listStyle(InsetGroupedListStyle())
        .navigationTitle("View3")
        .toolbar {
            ToolbarItem {
                Button(action: {isAddViewPresented.toggle()}, label: {
                    Label("Add", systemImage: "plus.circle.fill")
                })
            }
        }
        .sheet(isPresented: $isAddViewPresented, content: {
            Text("DestinationDummyView")
        })
    }
}
struct View4: View {
    @Binding var presentView4: Bool
    
    var body: some View {
        List {
            Button(action: {presentView4 = false}, label: {
                Text("Dismiss")
            })
        }
        .listStyle(InsetGroupedListStyle())
        .navigationTitle("View4")
    }
}

does anybody have a solution for that? Specifically, I need this in my application to delete records from the app (first the child, then the parent). thank you for any feedback and input! ☺️☺️☺️

Upvotes: 6

Views: 3042

Answers (1)

Asperi
Asperi

Reputation: 258443

Add .isDetailLink(false) to each NavigationLink in your views... and all works.

demo


    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)

Upvotes: 8

Related Questions