我是SwiftUI的新手(像大多数人一样),试图弄清楚如何删除我嵌入在NavigationView中的List上面的一些空白。

在此图像中,您可以看到列表上方有一些空白。

我想要完成的是:

我试过用:

.navigationBarHidden(true)

但这并没有带来任何明显的变化。

我现在像这样设置我的navigationview:

NavigationView {
    FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
        .navigationBarHidden(true)
}

其中FileBrowserView是一个带有List和FileCells的视图,定义如下:

List {
   Section(header: Text("Root")) {
       FileCell(name: "Test", fileType: "JPG",fileDesc: "Test number 1")
       FileCell(name: "Test 2", fileType: "txt",fileDesc: "Test number 2")
       FileCell(name: "test3", fileType: "fasta", fileDesc: "")
    }
}

我想指出的是,这里的最终目标是,您将能够单击这些单元格来更深入地导航到文件树中,因此在更深入的导航中应该在栏上显示一个后退按钮,但在我的初始视图中,我不希望顶部出现这样的任何东西。


当前回答

我有一个类似的问题,当工作在一个应用程序,TabView应该显示一旦用户登录。

正如@graycampbell在他的评论中建议的那样,TabView不应该嵌入到NavigationView中,否则“空白”将会出现,即使使用.navigationBarHidden(true)

我使用ZStack来隐藏NavigationView。注意,对于这个简单的示例,我使用@State和@Binding来管理UI可见性,但是您可能希望使用更复杂的东西,例如环境对象。

struct ContentView: View {

    @State var isHidden = false

    var body: some View {
        
        ZStack {
            if isHidden {
                DetailView(isHidden: self.$isHidden)
            } else {
                NavigationView {
                    Button("Log in"){
                        self.isHidden.toggle()
                    }
                    .navigationBarTitle("Login Page")
                }
            }
        }
    }
}

当我们按下Log In按钮时,初始页面消失,DetailView被加载。当我们切换注销按钮时,登录页面重新出现

struct DetailView: View {
    
    @Binding var isHidden: Bool
    
    var body: some View {
        TabView{
            NavigationView {
                Button("Log out"){
                    self.isHidden.toggle()
                }
                .navigationBarTitle("Home")
            }
            .tabItem {
                Image(systemName: "star")
                Text("One")
            }
        }
    }
}

其他回答

NavigationView的目的是在视图的顶部添加导航栏。在iOS中,有两种导航条:大导航条和标准导航条。

如果你不想要导航栏:

FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))

如果你想要一个大的导航栏(通常用于顶级视图):

NavigationView {
    FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
    .navigationBarTitle(Text("Title"))
}

如果你想要一个标准(内联)导航栏(通常用于子级别视图):

NavigationView {
    FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
    .navigationBarTitle(Text("Title"), displayMode: .inline)
}

希望这个答案对你有所帮助。

更多信息:苹果文档

类似于@graycampbell的回答,但更简单一点:

struct YourView: View {

    @State private var isNavigationBarHidden = true

    var body: some View {
        NavigationView {
            VStack {
                Text("This is the master view")
                NavigationLink("Details", destination: Text("These are the details"))
            }
                .navigationBarHidden(isNavigationBarHidden)
                .navigationBarTitle("Master")
                .onAppear {
                    self.isNavigationBarHidden = true
                }
                .onDisappear {
                    self.isNavigationBarHidden = false
                }
        }
    }
}

设置标题是必要的,因为它显示在您导航到的视图中的后退按钮旁边。

我知道我有点晚了,但我刚刚用上面的答案解决了这个问题: 如何摆脱空间嵌套的NavigationView与SwiftUI

如果该页面的内容发生变化,我将在下面解释答案。

只在任何需要导航的视图的最顶层使用NavigationView包装器,无论嵌套的子视图往下走多远。它们都已经有NavigationView属性,你可以在子视图中的任何时候调用NavigationLink。我在子视图周围有很多额外的NavigationView包装,删除它们可以删除额外的空白,同时保留所有导航链接的功能。

我必须从屏幕1导航到屏幕2。如果我像上面那样使用导航栏,导航栏将被隐藏,但它的空间仍然存在(高度的空间)在屏幕1中。

最后,我有自己的解决方案,在NavigationView内的任何视图中使用这段代码,不关心navigationBarTitle。就像这样:

Screen1:

NavigationView {
    SomeView {
        NavigationLink {
        // go to screen2
        }
    }.navigationBarHidden(true)
}

Screen2:

NavigationView {
// some Views
}.navigationBarHidden(true)

我尝试在我的Vstack的花括号的末尾添加.navigationBarHidden(true),就像这样

NavigationView { Vstack(){"some Code"}.navigationBarHidden(true)}

导航栏消失了,但如果我在导航栏的花括号后面添加。navigationbarhidden (true),就像这样

    NavigationView { Vstack(){"some Code"}}.navigationBarHidden(true)

导航栏不会消失