Swiftui tabview 布局问题

Posted

技术标签:

【中文标题】Swiftui tabview 布局问题【英文标题】:Swiftui tabview layout issue 【发布时间】:2021-02-04 04:12:02 【问题描述】:

我尝试过像以下屏幕截图这样的布局。基本上是一个长的垂直滚动视图,带有许多圆角窗格。

我的代码如下:

struct DetailView: View 

@EnvironmentObject var modelData: ModelData

var body: some View 
    ZStack 
        Image("Dummy")
            .resizable()
            .aspectRatio(contentMode: .fill)
            .opacity(0.2)
            .frame(width: .infinity, height: .infinity)
            .edgesIgnoringSafeArea(.all)
        
    ScrollView(.vertical, showsIndicators: false) 
        VStack(alignment: .leading, spacing: 0) 
            
            TabView 
                
                VStack(alignment: .leading, spacing:0) 
                    HStack 
                        Text("A long Text title").font(.title)
                        Spacer()
                    .frame(width:UIScreen.main.bounds.size.width*0.9)
                    HStack 
                        Text("A long Text title").font(.title)
                        Spacer()
                    .frame(width:UIScreen.main.bounds.size.width*0.9)
                    HStack 
                        Text("A long Text title").font(.title)
                        Spacer()
                    .frame(width:UIScreen.main.bounds.size.width*0.9)
                    HStack 
                        Text("A long Text title").font(.title)
                        Spacer()
                    .frame(width:UIScreen.main.bounds.size.width*0.9)
                
                
            .tabViewStyle(PageTabViewStyle())
            .background(Color.green)
            
            TabView 
                ImageView()
                    .frame(width:UIScreen.main.bounds.size.width*0.9)
                    .cornerRadius(UIConstants.cardCornerRadius)
                ImageView()
                    .frame(width:UIScreen.main.bounds.size.width*0.9)
                    .cornerRadius(UIConstants.cardCornerRadius)
                ImageView()
                    .frame(width:UIScreen.main.bounds.size.width*0.9)
                    .cornerRadius(UIConstants.cardCornerRadius)
            
            .tabViewStyle(PageTabViewStyle())
            .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
            .background(Color.red)
            
            TabView 
                TextInfoView()
                    .frame(width:UIScreen.main.bounds.size.width*0.9)
                    .cornerRadius(UIConstants.cardCornerRadius)
                    .padding([.horizontal])
            .tabViewStyle(PageTabViewStyle())
            .background(Color.green)
            
            TabView 
                TextInfoView()
                    .frame(width:UIScreen.main.bounds.size.width*0.9)
                    .cornerRadius(UIConstants.cardCornerRadius)
                    .padding([.horizontal])
            .tabViewStyle(PageTabViewStyle())
            .background(Color.purple)
        
    
    

struct TextInfoView: View 
    var body: some View 
        VStack 
            Text("Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview. Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview.Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview.Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview.Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview.Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview.").padding()
        
        .background(Color.yellow)
    


struct ImageView: View 
    var body: some View 
        Image("Dummy")
            .resizable()
            .aspectRatio(contentMode: /*@START_MENU_TOKEN@*/.fill/*@END_MENU_TOKEN@*/)
            .frame(height:UIScreen.main.bounds.size.height*0.7)
    

结果如下:

这里有几个问题:

    您可以看到我也尝试用 TabView 包装 TextInfoView。这是因为如果我不将它包含在 TabView 中,它无法与上面带有 ImageView 的 TabView 对齐。有什么方法可以解决这个问题?

    在顶部,绿色区域。为什么文本周围有这么大的填充?我怎样才能去除那些额外的绿色区域?我希望它在顶部和底部都很紧。

    如果我不为绿色区域文本添加 .frame() ,我发现文本消失了,无法向左对齐。有什么方法可以解决吗?

【问题讨论】:

【参考方案1】:

 struct DetailViews: View 
        
        var body: some View 
            
            ZStack 
                Color.green.edgesIgnoringSafeArea(.all)
                ScrollView(.vertical, showsIndicators: false) 
                    
                    VStack(spacing: 0) 
                        VStack
                            Text("A long Text Title")
                            Text("A long Text Title")
                            Text("A long Text Title")
                            Text("A long Text Title")
                        
                        .frame(maxWidth: .infinity)
                        .background(Color.yellow)
                        
                        
                        
                        TabView 
                            ImageView()
                                .frame(width:UIScreen.main.bounds.size.width*0.9)
                                .cornerRadius(15)
                            ImageView()
                                .frame(width:UIScreen.main.bounds.size.width*0.9)
                                .cornerRadius(15)
                            ImageView()
                                .frame(width:UIScreen.main.bounds.size.width*0.9)
                                .cornerRadius(15)
                        
                        .tabViewStyle(PageTabViewStyle())
                        .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
                        .background(Color.red)
                        
                        TextInfoView()
                            .cornerRadius(15)
                            .padding()
                            .background(Color.blue)
                        TextInfoView()
                            .cornerRadius(15)
                            .padding()
                            .background(Color.purple)
                        
                    
                    
                
            
            
        
    

    struct TextInfoView: View 
        var body: some View 
            VStack 
                Text("Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview. Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview.Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview.Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview.Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview.Learn how to use SwiftUI to compose rich views out of simple ones, set up data flow, and build the navigation while watching it unfold in Xcode’s preview.")

.fixedSize(horizontal: false, vertical: true).padding()//added
            
            .background(Color.yellow)
        
    

【讨论】:

我试过代码,发现文字在iPhone 11 Pro上无法全部显示。我的意思是黄色区域最后会导致“....”。有什么方法可以解决这个问题? 我完全使用了代码,但行为不同。 “...”分页指示器位于图像下方。 @UfukKöşker 请您添加一些解释,为什么您认为您的代码可以解决问题?另请参阅How to Answer。

以上是关于Swiftui tabview 布局问题的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:在 TabView 中调整图像的位置

更改 TabView (SwiftUI) 中未选中图标的颜色

ScrollView 中的 SwiftUI TabView

SwiftUI TabView 不更新视图

单击 UIView 时从 UIView 内部的标签获取文本

TabView 在为 SwiftUI 设置动画的选项卡之间切换