iOS 如果 navigationViewStyle 堆栈,带有导航视图的视图上的 15 个 SwiftUI 条件使得 NavigationBar 配置被忽略

iOS 15 SwiftUI Conditionals on a view with Navigation View makes NavigationBar config to be ignore if navigationViewStyle stack

一直在到处寻找这个,但找不到任何相关信息,我认为是一个错误,也许不是。

我需要 NavigationView.navigationViewStyle(.stack) 将其堆叠在 iPad 上并使其看起来与 iphone 相同,现在假设您有以下视图:

import SwiftUI

struct ContentView: View {
    @State var isShowingProfile = false
    @State var isNavigationViewShowing = true
    
    var body: some View {
        if isNavigationViewShowing {
            NavigationView {
                VStack {
                    Button("Simple view") {
                        isNavigationViewShowing = false
                    }
                    .padding()
                    Button("Profile navigation") {
                        isShowingProfile = true
                        
                    }
                    .padding()
                    NavigationLink(
                        destination: ProfileView(),
                        isActive: $isShowingProfile
                    ) {
                        EmptyView()
                    }
                }
                .frame(
                    minWidth: 0,
                    maxWidth: .infinity,
                    minHeight: 0,
                    maxHeight: .infinity
                )
                .background(Color.gray)
                .navigationBarHidden(true)
            }
            .navigationViewStyle(.stack)
        } else {
            VStack {
                Button("Show NavigationView"){
                    isNavigationViewShowing = true
                    
                }
                .padding()
            }
            .frame(
                minWidth: 0,
                maxWidth: .infinity,
                minHeight: 0,
                maxHeight: .infinity
            ).background(Color.yellow)
        }
    }
}

struct ProfileView: View {
    var body: some View {
        Text("This is a profile")
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

好吧,这只是显示这 3 个简单的视图:

到这里一切都很好。

问题是当导航到“简单视图”然后点击“显示 NavigationView”导航回 NavigtionView 时。

该应用程序打开第一个视图 (NavigationView),但 NavigationView 忽略了 .navigationBarHidden(true),只在顶部显示一个大空 space。事实上,它会忽略 .navigationBarTitleDisplayMode(.inline) 之类的东西,只显示导航栏的大版本

这在所有 iOS 14.x 中都可以正常工作,但在 iOS 上 15.0 似乎已损坏。 iOS 15.1 beta 上的行为仍然相同。

知道发生了什么事吗?我对更改视图上的条件并不感兴趣,因为现实生活中的应用程序更复杂。

此外,我尝试了 ViewBuilder,但没有成功。如果我取出 .navigationViewStyle(.stack) 它在 iOS 15 上一切正常,但是 iPad 上的视图是侧边菜单。

非常感谢任何提示或帮助,您应该能够在模拟器和真实设备中重现。

Video of the explained above

我认为更好的解决方案是不让 NavigationView 有条件。没有理由你的条件不能只生活在 NavigationView。您只是不想显示栏。因此,这段代码似乎符合要求:

struct ContentView: View {
    @State var isShowingProfile = false
    @State var isNavigationViewShowing = true
    
    var body: some View {
        NavigationView {
            Group {
                if isNavigationViewShowing {
                    VStack {
                        Button("Simple view") {
                            isNavigationViewShowing = false
                        }
                        .padding()
                        Button("Profile navigation") {
                            isShowingProfile = true
                            
                        }
                        .padding()
                        NavigationLink(
                            destination: ProfileView(),
                            isActive: $isShowingProfile
                        ) {
                            EmptyView()
                        }
                    }
                    .frame(
                        minWidth: 0,
                        maxWidth: .infinity,
                        minHeight: 0,
                        maxHeight: .infinity
                    )
                    .background(Color(UIColor.systemGray6))
                } else {
                    VStack {
                        Button("Show NavigationView"){
                            isNavigationViewShowing = true
                            
                        }
                        .padding()
                    }
                    .frame(
                        minWidth: 0,
                        maxWidth: .infinity,
                        minHeight: 0,
                        maxHeight: .infinity
                    ).background(Color.yellow)
                }
            }
            .navigationBarHidden(true)
        }
        .navigationViewStyle(.stack)
    }
}

我使用 Group 只是为了将 .navigationBarHidden(true) 放在正确的位置,以便代码可以编译。

这是您要寻找的行为吗?

    import SwiftUI

struct ContentView: View {
    @State private var isShowingProfile = false
    @State private var showSimple = false
    
    var body: some View {
        
        NavigationView {
            VStack {
                Button("Simple view") {
                    showSimple = true
                }
                .padding()
                Button("Profile navigation") {
                    isShowingProfile = true
                    
                }
                .padding()
                NavigationLink(destination: ProfileView(), isActive: $isShowingProfile) {
                    EmptyView()
                }
            }
            .fullScreenCover(isPresented: $showSimple, onDismiss: {
                print("Dismissed")
            }, content: {
                SimpleView()
            })
            .frame(
                minWidth: 0,
                maxWidth: .infinity,
                minHeight: 0,
                maxHeight: .infinity
            )
            .background(Color.gray)
            .navigationBarHidden(true)
        }
        .navigationViewStyle(.stack)
        
    }
}

struct ProfileView: View {
    var body: some View {
        Text("This is a profile")
    }
}

struct SimpleView: View {
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        VStack {
            Button("Show NavigationView") {
                presentationMode.wrappedValue.dismiss()
            }
            .padding()
        }
        .frame(
            minWidth: 0,
            maxWidth: .infinity,
            minHeight: 0,
            maxHeight: .infinity
        ).background(Color.yellow)
    }
}