1

I have the following:

@State private var showNext = false

...
    NavigationStack {
        VStack {
            NavigationLink(destination: NextView(showSelf: $showNext),
                           isActive: $showNext) { EmptyView() }

            Button("Show Next") {
                showNext = true
            }
        }
    }

...

struct NextView: View {
    @Binding var showSelf: Bool

    var body: some View {
        Text("Next")
         .navigationTitle("Next")

        Button("Dismiss") {
            showSelf = false
        }
            .padding(30)
    }
}

When tapping Show Next, the NextView is shown as expected.

But when tapping Dismiss, nothing happens.

Turns out that showSelf was already false before it's set to false. So it seems something went wrong with passing the binding into NextView.

What could be wrong?

meaning-matters
  • 21,929
  • 10
  • 82
  • 142

3 Answers3

2

The issue was caused by NavigationStack. When I replaced it with NavigationView it worked as expected.

The isActive binding of NavigationLink does not appear to work (or to be supported) when embedded in a NavigationStack.

meaning-matters
  • 21,929
  • 10
  • 82
  • 142
1

isActive binding is for NavigationView, try:

NavigationView {
    ...
}
.navigationViewStyle(.stack)`
malhal
  • 26,330
  • 7
  • 115
  • 133
  • 1
    Why does the [documentation](https://developer.apple.com/documentation/swiftui/navigationview) not talk about a required main and detail view? How does use of `EmptyView` cause my binding to have the wrong value? What do you mean with "navigation to break"; I didn't talk about that? – meaning-matters Sep 26 '22 at 21:50
  • I meant isActive breaking – malhal Sep 26 '22 at 22:12
  • Thanks for you time! Your `NextView` doesn't fix this issue. Where did you read that `NavuigationView` requires a main and detail view? – meaning-matters Sep 27 '22 at 05:53
  • Text(“Select a note”) https://developer.apple.com/documentation/swiftui/navigationview – malhal Sep 27 '22 at 09:14
  • https://stackoverflow.com/a/73873498/1971013 – meaning-matters Sep 27 '22 at 20:31
0

You are trying to mix code for iOS >= 16 (NavigationStack) and for iOS < 16 (the previous way to handle NavigationLink). Similarly for the dismiss part, which is iOS < 15.

Here is your code for iOS 16:

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            VStack {
                NavigationLink {
                    NextView()
                } label: {
                    Text("Show next view")
                }
            }
        }
    }
}

struct NextView: View {
    @Environment(\.dismiss) private var dismiss
    var body: some View {
        VStack {
            Text("You are in the next view")
            Button("Dismiss", action: dismiss.callAsFunction)
        }
        .navigationTitle("Next")
    }
}

I have used the simplest construction of NavigationLink. A more complex one would be used in conjunction with .navigationDestination. The best examples I have found are here:

And if you want to dive more into very strange behaviour of the stack, you can look at my post here: Found a strange behaviour of @State when combined to the new Navigation Stack - Is it a bug or am I doing it wrong?

If you need to produce code for iOS < 16, you should replace NavigationStack with NavigationView and work from there.

Adkarma
  • 23
  • 6