2

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?

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

Comments

1

isActive binding is for NavigationView, try:

NavigationView {
    ...
}
.navigationViewStyle(.stack)`

5 Comments

Why does the documentation 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?
I meant isActive breaking
Thanks for you time! Your NextView doesn't fix this issue. Where did you read that NavuigationView requires a main and detail view?
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.