简体   繁体   English

SwiftUI - 放置在 NavigationView 中时 VStack 未填满整个屏幕

[英]SwiftUI - VStack not filling entire screen when placed in NavigationView

It seems like when placed in a NavigationView, VStacks won't fill the entire vertical space.看起来当放置在 NavigationView 中时,VStacks 不会填满整个垂直空间。 Or maybe I'm doing something wrong?或者也许我做错了什么?

var body: some View {
    NavigationView {
        VStack(alignment: .leading) {
            Text("HEY")
        }
        .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
        .background(.gray)
    }
    .navigationBarTitle("Reçu", displayMode: .inline)
}

I also customized UINavigationBar to give it some color and set navigationBarTitle to inline.我还定制了UINavigationBar给它一些颜色并将navigationBarTitle设置为内联。

I tried 2 workarounds:我尝试了 2 个解决方法:

  • .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: Alignment.topLeading)
  • .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)

The first one fills more vertical space, but not all of it.第一个填充更多的垂直空间,但不是全部。

在此处输入图像描述

It looks like there are two navigation views added to your view hierarchy.看起来有两个导航视图添加到您的视图层次结构中。

  • If the parent view has a NavigationView and you are going into child view using NavigationLink then you don't have to add a NavigationView to your child view it has automatically added.如果父视图有NavigationView并且您要使用NavigationLink进入子视图,那么您不必将NavigationView添加到它自动添加的子视图中。
  • If you are directly setting new rootView for your UIHostingController then add NavigationView into that new rootView .如果您直接为UIHostingController设置新的rootView ,则将NavigationView添加到新的rootView中。

In order to have a background color for your view I suggest you go for the ZStack view:为了为您的视图设置背景颜色,我建议您为ZStack视图使用 go:

struct ContentView: View {
    var body: some View {
        NavigationView {
            ZStack {
                Color.gray                
            }
            .edgesIgnoringSafeArea(.all)
            .navigationBarTitle("Reçu", displayMode: .inline)
        }
    }
}

You can even create you custom view (to reuse wherever you want) that takes a colour as a parameter:您甚至可以创建以颜色为参数的自定义视图(以便在任何地方重复使用):

struct BgColorView<Content>: View where Content: View{
    private let color: Color
    private let content: () -> Content

    init(color: Color, @ViewBuilder content: @escaping () -> Content) {
        self.color = color
        self.content = content
    }
    var body: some View {
        ZStack {
            color.edgesIgnoringSafeArea(.all)
            content()
        }
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            BgColorView(color: Color.green) {
                Text("Hello world!")
            }
            .navigationBarTitle("Reçu", displayMode: .inline)
        }
    }
} 

For the second issue, it strictly depends on your needs.对于第二个问题,这完全取决于您的需求。 The easiest way to have content aligned top-left is using the Spacer view.使内容左上角对齐的最简单方法是使用Spacer视图。

struct ContentView: View {
    var body: some View {
        NavigationView {
            BgColorView(color: Color.green) {
                VStack {
                    HStack {
                        Text("Hello world!")
                        Spacer()
                    }
                    Spacer()
                }
            }
            .navigationBarTitle("Reçu", displayMode: .inline)
        }
    }
}

But again, it depends on what you're trying yo get.但同样,这取决于你想要得到什么。

It looks like you're currently setting the navigationBarTitle of your NavigationView .看起来您当前正在设置NavigationViewnavigationBarTitle However, if you remove the navigationBarTitle on the list that might remove the space you're trying to clean up.但是,如果您删除列表中的navigationBarTitle ,可能会删除您尝试清理的空间。 See this other stack overflow answer on how to do that: How to remove the default Navigation Bar space in SwiftUI NavigiationView请参阅有关如何执行此操作的其他堆栈溢出答案: How to remove the default Navigation Bar space in SwiftUI NavigiationView

This is Apple's official tutorial, where they also put the navigationBarTitle on the List instead of the actual NavigationView : https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation#set-up-navigation-between-list-and-detail这是 Apple 的官方教程,他们还将navigationBarTitle放在 List 而不是实际的NavigationView上: https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation#set-up-navigation-between -列表和详细信息

This is a sample that shows you how to switch a custom view or screen:这是一个示例,向您展示如何切换自定义视图或屏幕:

struct MyView: View {
    @State var isActive = false
    var body: some View {
        NavigationView {
                VStack(alignment: .leading) {
                    Button(action: {
                        self.isActive = true
                    }) {
                        Text("Hey")
                    }
                }
                .frame(width: 100, height: 100, alignment: .center)
                .background(Color.blue)
                .foregroundColor(Color.white)
            }
        .fullScreenCover(isPresented: self.$isActive, content: {
            Text("This is full screen View or custom view")
        })
            .navigationBarTitle("Reçu", displayMode: .inline)
    }
}

First of all thank you Niley for pointing the issue, but there is one case missing: What if I want a new NavigationView in ChildNavigation View?首先感谢Niley指出这个问题,但是缺少一个案例:如果我想要在 ChildNavigation View 中使用新的 NavigationView 怎么办? The answer is just to add these three lines in content view of navigation view:答案就是在导航视图的内容视图中添加这三行:

.navigationBarTitle(Text(""), displayMode: .inline) .navigationBarTitle(文本(“”),显示模式:.inline)

.navigationBarHidden(true) .navigationBarHidden(true)

.navigationBarBackButtonHidden(true) .navigationBarBackButtonHidden(true)

NavigationView{
    VStack{} or HStack{} or ZStack{}
    .navigationBarTitle(Text(""), displayMode: .inline)
    .navigationBarHidden(true)
    .navigationBarBackButtonHidden(true)
}

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

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