簡體   English   中英

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”。

如果我運行該項目並點擊NavigationLink ,則DestinationView顯示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
            }
        }
    }

安全區域布局指南存在問題

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)
    }
}

快樂編碼...

編輯:使用接受的答案,因為它是一個清潔的解決方案。


我遇到了這個錯誤並最終使用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)
        }
    }
}

對我來說,通過視圖層次結構傳遞綁定並不是最佳選擇,將狀態添加到環境變量是可取的。

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 模擬器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM