SwiftUI TabView 与基于 Content 的 PageTabViewStyle 动态高度

Ese*_*era 13 ios tabview swift swiftui

如何使 SwiftUI 的高度TabView调整PageTabViewStyle为内容的高度?

我有SwiftUI如下观点:

struct TabViewDynamicHeight: View {
    var body: some View {
        VStack {
            TabView {
                ForEach(0..<5, id: \.self) { index in
                    VStack {
                        Text("Text \(index)")
                        Text("Text \(index)")
                        Text("Text \(index)")
                    }
                }
            }
            .tabViewStyle(PageTabViewStyle())
            .background(Color.red)
            .fixedSize(horizontal: false, vertical: true)
        }
        .background(Color.blue)
    }
}
Run Code Online (Sandbox Code Playgroud)

这会产生如下输出:

在此输入图像描述

可以看到,内容被TabView截断了。我知道我可以删除.fixedSize,但视图看起来像这样:

在此输入图像描述

我希望 TabView 能够响应内容的高度。关于如何实现这一目标有什么想法吗?

Asp*_*eri 4

一种可能的方法是在运行时动态获取内容矩形并通过视图首选项传输到父级,因此父级可以将其设置为框架以适应内容。

使用 Xcode 13.3 / iOS 15.4 进行测试

演示

这是主要部分:

VStack {
    Text("Text \(index)")
    Text("Text \(index)")
    Text("Text \(index)")
}
.frame(maxWidth: .infinity)
.background(GeometryReader {
    Color.clear.preference(key: ViewRectKey.self,
                                  value: [$0.frame(in: .local)])
})

// ...

.frame(height: rect.size.height
         + 60 /* just to avoid page indicator overlap */)
.onPreferenceChange(ViewRectKey.self) { rects in
    self.rect = rects.first ?? .zero
}
Run Code Online (Sandbox Code Playgroud)

项目中完整的测试代码在这里

  • @DucDang,它是ViewRectKey首选项键,它在引用的测试项目的不同模块中声明 (2认同)