SwiftUI - NavigationLink 视图中的 NavigationBar 快速显示然后消失

SwiftUI - NavigationBar in View from NavigationLink quickly showing then disappearing

我有一个 ContentView 包含一个 NavigationView 导致 DestinationView。我想在 ContentView 中隐藏导航栏,但在 DestinationView 中显示它。为了将它隐藏在 ContentView 中,我将 navigationBarHidden 设置为 true 并给 navigationBarTitle 一个空字符串。 在 DestinationView 中,我将 navigationBarHidden 设置为 false 并将其命名为 "DestinationView".

如果我 运行 项目并点击 NavigationLinkDestinationView 会显示 NavigationBar,但会在视图出现后迅速隐藏它。有人可以帮我解决这个问题吗?

struct ContentView: View {
    var body: some View {
        NavigationView {
            ZStack {
                Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
                NavigationLink(destination: DestinationView()) {
                    ZStack {
                        Color.green.frame(width: 200, height: 200)
                        Text("Tap me")
                    }
                }
            }
            .navigationBarTitle("")
            .navigationBarHidden(true)
        }
    }
}

struct DestinationView: View {
    var body: some View {
        List {
            Text("1")
            Text("2")
        }
        .navigationBarTitle("DestinationView")
        .navigationBarHidden(false)
    }
}

您需要使用变量来实现这一点并将其与您的目的地绑定

struct ContentView: View {
         @State var isNavigationBarHidden: Bool = true
        var body: some View {
            NavigationView {

                ZStack {
                    Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
                    NavigationLink(destination: DestinationView(isNavigationBarHidden: self.$isNavigationBarHidden)) {
                        ZStack {
                            Color.green.frame(width: 200, height: 200)
                            Text("Tap me")
                        }
                    }

                }
                .navigationBarHidden(self.isNavigationBarHidden)
                .navigationBarTitle("")
                .onAppear {
                    self.isNavigationBarHidden = true
                }
            }
        }
    }

    struct DestinationView: View {
        @Binding var isNavigationBarHidden: Bool
        var body: some View {
            List {
                Text("1")
                Text("2")
            }
            .navigationBarTitle("DestinationView")

            .onAppear {
                self.isNavigationBarHidden = false
            }
        }
    }

编辑:使用 ,因为它是 更清洁的解决方案。


我遇到了这个错误并最终使用 UIViewControllerRepresentable 包装了一个控制器,该控制器在其 viewDidAppear 方法中设置了导航栏隐藏状态:

struct ContentView: View {
    var body: some View {
        NavigationView {
            ZStack {
                Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
                NavigationLink(destination: DestinationView()) {
                    ZStack {
                        Color.green.frame(width: 200, height: 200)
                        Text("Tap me")
                    }
                }
            }
            .navigationBarTitle("")
            .navigationBarHidden(true)
        }
    }
}

struct DestinationView: View {
    var body: some View {
        List {
            Text("1")
            Text("2")
        }
        .navigationBarTitle("DestinationView")
        .navigationBarHidden(false)
        .background(HorribleHack())
    }
}

struct HorribleHack: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> HorribleHackViewController {
        HorribleHackViewController()
    }

    func updateUIViewController(_ uiViewController: HorribleHackViewController, context: Context) {
    }
}

class HorribleHackViewController: UIViewController {
    override func viewDidAppear(_ animated: Bool) {
        DispatchQueue.main.async {
            self.navigationController?.setNavigationBarHidden(false, animated: false)
        }
    }
}

安全区域布局指南存在问题

struct ContentView: View {
    var body: some View {
        NavigationView {
            ZStack {
                Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
                VStack {
                    NavigationLink(destination: DestinationView()) {
                        ZStack {
                            Color.green.frame(width: 200, height: 200)
                            Text("Tap me")
                        }
                    }
                }
            }.edgesIgnoringSafeArea(.all)
            .navigationBarHidden(true)
        }
    }
}

struct DestinationView: View {
    var body: some View {
        VStack {
            List {
                Text("1")
                Text("2")
            }
        }.navigationBarTitle("DestinationView")
        .navigationBarHidden(false)
    }
}

快乐编码...

对我来说,通过视图层次结构传递绑定并不是最佳选择,将状态添加到环境变量中更可取。

class SceneState: ObservableObject {
    @Published var isNavigationBarHidden = true
}


class SceneDelegate: UIResponder, UIWindowSceneDelegate {
...
    var sceneState = SceneState()

...
    let contentView = ContentView().environmentObject(sceneState)
...
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            View1()
        }
    }
}

struct View1: View {
    @EnvironmentObject var sceneState: SceneState
    @State private var showView2: Bool = false

    var body: some View {
        VStack {
            Text("NO nav bar.")
            Button("Go to View2") {
                self.showView2 = true
            }
            NavigationLink(destination: View2(), isActive: $showView2, label: {EmptyView()})
        }
        .navigationBarHidden(self.sceneState.isNavigationBarHidden)
        .navigationBarTitle("")
        .navigationBarBackButtonHidden(self.sceneState.isNavigationBarHidden)
    }
}


struct View2: View {
    @EnvironmentObject var sceneState: SceneState

     var body: some View {
        VStack {
            Text("WITH nav bar.")
        }
            .navigationBarHidden(self.sceneState.isNavigationBarHidden)
            .navigationBarTitle("WWDC")
            .navigationBarBackButtonHidden(self.sceneState.isNavigationBarHidden)
            .onAppear {
                self.sceneState.isNavigationBarHidden = false
        }
    }
}

这个问题实际上有一个非常简单的解决方案。经过多次尝试,我想通了,你必须将 .navigationBarHidden(false) 直接添加到 NavigationLink 内的目标视图,如下所示:

struct ContentView: View {
    var body: some View {
        NavigationView {
            ZStack {
                Color.red.frame(maxWidth: .infinity, maxHeight: .infinity)
                NavigationLink(destination: DestinationView()
                   .navigationBarHidden(false)) {
                    ZStack {
                        Color.green.frame(width: 200, height: 200)
                        Text("Tap me")
                    }
                }
            }
            .navigationBarTitle("")
            .navigationBarHidden(true)
        }
    }
}

struct DestinationView: View {
    var body: some View {
        List {
            Text("1")
            Text("2")
        }
        .navigationBarTitle("DestinationView")
        .navigationBarHidden(false)
    }
}

会如愿以偿,出现后不会消失。

我 运行 iOS 14 模拟器上的这段代码和导航栏没有隐藏,所以我认为这可能是 iOS 13 的问题。我有一个类似的导致导航栏在 iOS 13.5 模拟器上消失的问题和我的代码在 iOS 14.4 模拟器上运行良好。