如何计算 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 中的标签栏高度?的主要内容,如果未能解决你的问题,请参考以下文章