顶部细节视图中不会消失的额外空间 (SwiftUI)

Posted

技术标签:

【中文标题】顶部细节视图中不会消失的额外空间 (SwiftUI)【英文标题】:Extra space in the Top of Detail View that won't go away (SwiftUI) 【发布时间】:2020-07-02 18:18:01 【问题描述】:

我在详细视图中有一个不会消失的额外空间。该视图来自 NavigationLink,但我尝试过使用或不使用 NavigationView。我试图用 NavigationView 替换 ScrollView 来包装它,但这没有用。我认为很多 Swift 编码人员都遇到过这个问题,并且没有适合我的正确答案。

这是我的详细视图

struct DetailView: View 
    var body: some View 
                
        ScrollView 
            VStack(alignment: .leading) 
                Text("Huge Font Recipe Title")
                .font(.system(size: 48, weight: .bold))
                .foregroundColor(.black)
                .padding([.leading, .top, .trailing])
                                            
                    VStack 
                        Image("img1")
                            .resizable()
                            .frame(width: 375, height: 375)
                            .aspectRatio(contentMode: .fit)
                            .frame(width: UIScreen.main.bounds.width)
                            
                        Spacer()

                            
                        .padding(.bottom)
                                                        

                    
                  
               
            

             
struct DetailView_Previews: PreviewProvider 
    static var previews: some View 
        DetailView()
    

这是包含 NavigationView 的父视图(内容视图)

import SwiftUI

struct ContentView: View 
    var body: some View 

        NavigationView 

            ScrollView (showsIndicators: false) 
                    VStack(spacing: 20) 
                        ForEach(recipecardData)  item in

                            NavigationLink(
                            destination: DetailView()) 

                            RecipeCards( card: item)
                        
                    
                

                        
        .navigationBarTitle("Navigation")
                    
            




            struct RecipeCards: View 

                var card: RecipeCard

                var body: some View 

                    ZStack 
                        Image(card.imageName)
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: 334, height: 335)
                            .cornerRadius(10)
                            .padding()
                            .shadow(radius: 16)

                        Rectangle()
                            .foregroundColor(.clear)
                            .background(LinearGradient(gradient: Gradient(colors: [.red, .blue]), startPoint: .bottom, endPoint: .top)
            )
                            .frame(width: 334, height: 335)
                           .cornerRadius(10)


                        HStack 

                            Text(card.title)
                                .font(.system(size: 27,weight: .bold))
                                .foregroundColor(.white)
                                .frame(minWidth: 10, maxWidth: .infinity, alignment: .leading)
                                .lineLimit(2)
                                .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 20))

                            

                        .padding(.bottom, 268)
                        .padding(EdgeInsets(top: 0, leading: 34, bottom: 0, trailing: 8))
                    
                
            


            struct RecipeCard: Identifiable 
                var id = UUID()
                var title: String
                var imageName: String

            

            let recipecardData =  [
            RecipeCard(title: "Title 1", imageName: "img1"),
            RecipeCard(title: "Title 2", imageName: "img2")
            ]


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

【问题讨论】:

你缺少很多依赖,请看How to create a Minimal, Reproducible Example 用上面的代码很难复制这个问题。您的 ParentView 中的 RecipeDetail() 在哪里?什么是 TabBarView()? @pawello2222 这是我在这里的第一个问题,请原谅糟糕的文档。我修复了上面的代码。现在应该可以工作了。 @davidev 我有多个视图,包括包含 TabBar 和 RecipeList 的 TabBarView。但是我简化了上面的代码,你现在应该可以运行它并看到问题了。谢谢你的帮助。 【参考方案1】:

NavigationBar 带有large 样式。您可以使用此修饰符使其更小:

.navigationBarTitle("Title", displayMode: .inline)


由于 OP 的评论而更新

如果你想在扩展内容的同时保持大标题,你应该考虑忽略安全区的top边缘:

.edgesIgnoringSafeArea(.top)

此外,您可能需要添加一些paddings 之前忽略安全区域以保留inline 导航大小。


重要

    注意所有这些修饰符都应该应用于目标视图。

    NavigationBar 将留在那里并防止触摸事件传递到下面的视图。如果你真的需要摆脱它,你应该使用.navigationBarHidden(true)

【讨论】:

嗨mojtaba,这解决了间距问题。谢谢你!但是,我希望用户看到大的 NavigationBarTitle。一定有别的解决办法吧? 也许,但这是另一个问题。当另一个人的答案与我的完全一样但2小时后,你为什么接受另一个人的答案? @刘易斯 @MojtabaHosseini 我相信 OP 也需要一个解释,而不仅仅是一个单一的解决方案。如果我不知道您在说什么,我假设您建议更改ContentView 中的navigationBarTitle。而且没有必要投反对票,我只是想帮忙:) 谢谢@MojtabaHosseini【参考方案2】:

您可以在DetailView 中将displayMode: .inline 设置为NavigationBar

struct DetailView: View 
    var body: some View 
        ScrollView 
            ...
        
        .navigationBarTitle("Some title", displayMode: .inline)
    

在导航的每个步骤中,您都可以设置不同的NavigationBar 标题。通过设置displayMode,您可以控制其样式(和高度)。

您的问题出现是因为在您的DetailView 中设置了一个 NavigationBar 标题(如果您没有明确指定它,它的样式将从父视图复制)。此外,您没有指定它的 text - 它是空的。

这意味着您在 NavigationBar 和图像标题之间没有额外的空格。这是一个 大的 NavigationBar 标题。

【讨论】:

【参考方案3】:

如果详细视图不需要标题,请在 DetailView 中使用 .navigationBarTitleDisplayMode(.inline) 而不是 .navigationBarTitle(...)

【讨论】:

以上是关于顶部细节视图中不会消失的额外空间 (SwiftUI)的主要内容,如果未能解决你的问题,请参考以下文章

使用 SwiftUI 解锁后状态栏消失

从子视图 SwiftUI 中删除 UI 元素

如何在没有额外空间的情况下更改 SwiftUI Picker 视图大小?

SwiftUI 检测视图何时不可见(有点视图会消失)并停止发布者

SwiftUI,删除VStack中视图之间的空间?

NavigationView 顶部的额外空间