简体   繁体   English

SwiftUI NavigationLink isActive 绑定未更新/工作

[英]SwiftUI NavigationLink isActive Binding Not Updated/Working

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.点击Show Next时, NextView会按预期显示。

But when tapping Dismiss , nothing happens.但是当点击Dismiss时,没有任何反应。

Turns out that showSelf was already false before it's set to false .原来showSelf在设置为false之前就已经是false了。 So it seems something went wrong with passing the binding into NextView .因此,将绑定传递给NextView似乎出了点问题。

What could be wrong?有什么问题吗?

The issue was caused by NavigationStack .该问题是由NavigationStack引起的。 When I replaced it with NavigationView it worked as expected.当我用NavigationView替换它时,它按预期工作。

The isActive binding of NavigationLink does not appear to work (or to be supported) when embedded in a NavigationStack .当嵌入NavigationStack时, NavigationLinkisActive绑定似乎不起作用(或不受支持)。

This kind of bug happens sometimes when you haven't provided your NavigationView with a detail view correctly, eg当您没有正确地为 NavigationView 提供详细视图时,有时会发生这种错误,例如

NavigationView {
    MainView()
    DetailView()
}

It tries to use another View further down the hierarchy that can cause things like isActive to break.它试图在层次结构的更下方使用另一个视图,这可能导致 isActive 之类的东西中断。 In your case there is a bug in NextView that might be contributing it, you've got 2 Views but don't have a container, try changing it to this:在您的情况下, NextView中可能存在一个错误,您有 2 个视图但没有容器,请尝试将其更改为:

struct NextView: View {
    @Binding var showSelf: Bool

    var body: some View {
        HStack {
            Text("Next")
            Button("Dismiss") {
                showSelf = false
            }
        }
        .navigationTitle("Next")
    }
}

Another thing non-standard is the use of EmptyView .另一件非标准的事情是EmptyView的使用。

You are trying to mix code for iOS >= 16 ( NavigationStack ) and for iOS < 16 (the previous way to handle NavigationLink ).您正在尝试混合 iOS >= 16 ( NavigationStack ) 和 iOS < 16 的代码(以前处理NavigationLink的方法)。 Similarly for the dismiss part, which is iOS < 15.同样对于 dismiss 部分,它是 iOS < 15。

Here is your code for iOS 16:这是 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 .我使用了最简单的NavigationLink结构。 A more complex one would be used in conjunction with .navigationDestination .一个更复杂的将与.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?如果您想更深入地了解堆栈的非常奇怪的行为,您可以在这里查看我的帖子: 在与新的导航堆栈组合时发现@State 的奇怪行为 - 这是一个错误还是我做错了?

If you need to produce code for iOS < 16, you should replace NavigationStack with NavigationView and work from there.如果您需要为 iOS < 16 生成代码,则应将NavigationStack替换为NavigationView并从那里开始工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM