[英]SwiftUI TabView with PageTabViewStyle dynamic height based on Content
如何使帶有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)
}
}
這會產生如下所示的 output:
可以看到, TabView
的內容被截斷了。 我知道,我可以刪除.fixedSize
,但視圖看起來像這樣:
我希望 TabView 響應內容的高度。 關於如何實現這一目標的任何想法?
一種可能的方法是在運行時動態獲取內容 rect 並通過視圖首選項傳輸給父級,因此父級可以將其設置為適合內容的框架。
用 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
}
我從 Asperi 的回答中獲得了靈感,但是我必須修改一些東西才能使其適用於我的情況。
在 TabView 的“內容”中,我添加了這些:
.overlay(GeometryReader { proxy in
Color.clear.preference(key: ViewRectKey.self, value: proxy.size)
})
.onPreferenceChange(ViewRectKey.self) { size in
if self.viewPagerSize.height == .zero {
self.viewPagerSize = size
}
}
其中 viewPagerSize 最初是:
@State var viewPagerSize: CGSize = .zero
我的 PreferenceKey 看起來像這樣:
struct ViewRectKey: PreferenceKey {
static let defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
總的來說,代碼如下所示:
@ViewBuilder
func createViewPager() -> some View {
TabView {
ForEach(views(), id: \.id) { _ in
createInformationSquareView()
.background(Color(.systemGray6))
.overlay(GeometryReader { proxy in
Color.clear.preference(key: ViewRectKey.self, value: proxy.size)
})
.onPreferenceChange(ViewRectKey.self) { size in
if self.viewPagerSize.height == .zero {
self.viewPagerSize = size
}
}
}
}
.cornerRadius(10)
.frame(height: self.viewPagerSize.height + 60)
.tabViewStyle(.page)
.indexViewStyle(.page(backgroundDisplayMode: .always))
.padding()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.