如何计算 SwiftUI 中的标签栏高度?

Posted

技术标签:

【中文标题】如何计算 SwiftUI 中的标签栏高度?【英文标题】:How to calculate Tab Bar height in SwiftUI? 【发布时间】:2020-01-31 19:24:24 【问题描述】:

我有一个播放器高度为屏幕高度 1/3 的页面。在频道下,滚动视图中有多个频道。我正在尝试将滚动视图部分的高度设置为从播放器底部到页面底部。我试图将其设置为(屏幕高度-(播放器高度)-(导航栏高度)-(标签栏高度))。但问题是标签栏的高度因设备而异。我尝试了以下代码:

.frame(height: (UIScreen.main.bounds.height) - ((UIScreen.main.bounds.height) * 2/6) - (geometry.safeAreaInsets.top + geometry.safeAreaInsets.bottom ) )

但看起来 geometry.safeAreaInsets.bottom 不包含标签栏高度。那么有什么方法可以在 SwiftUI 中进行计算,或者有没有其他方法可以实现类似的外观?

我只想在所有屏幕尺寸的播放器和标签栏之间放置包含通道的滚动视图。

【问题讨论】:

这能回答你的问题吗? Programmatically detect Tab Bar or TabView height in SwiftUI 【参考方案1】:

我刚开始研究 SwiftUI,但是...我的印象是 GeometryReader 应该为你处理这个问题。

试试这个:

struct Tab1View: View 
    var body: some View 
        GeometryReader  geometry in
            VStack 
                Text("Top == 1/3 height")
                    .frame(width: geometry.size.width, height: geometry.size.height / 3.0, alignment: .center)
                    .background(Color.init(red: 0.1, green: 0.1, blue: 0.5))
                    .foregroundColor(Color.white)
                    .border(Color.yellow)
                Text("Bottom == 2/3 height")
                    .frame(width: geometry.size.width, height: geometry.size.height * 2.0 / 3.0, alignment: .center)
                    .background(Color.init(red: 0.5, green: 0.1, blue: 0.1))
                    .foregroundColor(Color.white)
                    .border(Color.yellow)
            
            .frame(width: geometry.size.width,
                   height: geometry.size.height,
                   alignment: .topLeading)
        
    


struct Tab2View: View 
    var body: some View 
        Color.blue
    


struct MyTabView: View 
    var body: some View 

        TabView 
            //Text("The content of the first view")
            Tab1View()
                .tabItem 
                    Image(systemName: "phone.fill")
                    Text("First Tab")
            
            //Text("The content of the second view")
            Tab2View()
                .tabItem 
                    Image(systemName: "tv.fill")
                    Text("Second Tab")
            
        
    


struct MyTabView_Previews: PreviewProvider 
    static var previews: some View 
        MyTabView()
    

结果:

并且,旋转时自动调整到 TabBar 高度:


编辑

经过一番调查,看起来ScrollView 可以自行调整大小以填充可用空间,因此我们只需要设置顶视图的高度即可。

这是一个修改后的例子:

struct MyItemView: View 
    var itemDesc = "Testing"
    var geoWidth: CGFloat = 100
    var body: some View 
            Text("\(self.itemDesc)")
                .foregroundColor(Color.white)
                .padding(16.0)
                .frame(width: self.geoWidth, height: nil, alignment: .leading)
    


struct Tab1View: View 
    var body: some View 
        GeometryReader  geometry in
            VStack(spacing: 0.0) 
                Text("Top == 1/3 height")
                    .frame(width: geometry.size.width, height: geometry.size.height * 1.0 / 3.0, alignment: .center)
                    .background(Color.init(red: 0.1, green: 0.1, blue: 0.5))
                    .foregroundColor(Color.white)
                    .border(Color.yellow)

                ScrollView(.vertical) 
                    VStack(alignment: .leading, spacing: 0) 
                        ForEach((1...20), id: \.self) 
                            MyItemView(itemDesc: "This is item \($0)", geoWidth: geometry.size.width)
                                .background(Color.init(red: 0.5, green: 0.1, blue: 0.1))
                                .border(Color.yellow)
                        
                    
                
                .frame(width: geometry.size.width, height: nil, alignment: .leading)
            
        
    

struct Tab2View: View 
    var body: some View 
        GeometryReader  geometry in
            VStack 
                Text("Top == 1/3 height")
                    .frame(width: geometry.size.width, height: geometry.size.height * 1.0 / 3.0, alignment: .center)
                    .background(Color.init(red: 0.1, green: 0.1, blue: 0.7))
                    .foregroundColor(Color.white)
                    .border(Color.yellow)
                Text("Bottom == 2/3 height")
                    .frame(width: geometry.size.width, height: geometry.size.height * 2.0 / 3.0, alignment: .center)
                    .background(Color.init(red: 0.2, green: 0.6, blue: 0.1))
                    .foregroundColor(Color.white)
                    .border(Color.yellow)
            
        
    

struct MyTabView: View 
    var body: some View 
        TabView 
            Tab1View()
                .tabItem 
                    Image(systemName: "phone.fill")
                    Text("First Tab")
            
            Tab2View()
                .tabItem 
                    Image(systemName: "tv.fill")
                    Text("Second Tab")
            
        
    


struct MyTabView_Previews: PreviewProvider 
    static var previews: some View 
        MyTabView()
    

还有,新结果:

【讨论】:

设置GeometryReader中嵌入的VStack的frame是多余的吧? 很可能/很可能。我开始让 VStack 填充高度,认为会有一个像 UIStackView 这样的“分布:填充”设置。所以,是的。 @user3441734 - 是的...快速测试显示不需要在VStack 上设置.frame @user3441734 - 正如我所提到的,我刚刚开始查看 SwiftUI,所以请原谅任何明显的错误。我已经通过实现下 2/3 空间的滚动视图来编辑我的答案。

以上是关于如何计算 SwiftUI 中的标签栏高度?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 的标签栏的特定视图中隐藏导航栏?

在 SwiftUI 中的特定页面上隐藏标签栏

如何在 SwiftUI 中删除主要内容视图和标签栏之间的间距?

更改标签栏图标图像 SwiftUI

带有 SwiftUI 的标签栏上方的额外导航视图

xib 中的自动布局 - 子视图的高度与导航栏和标签栏之间的空间成正比