我正在尝试创建一个在顶层具有垂直滚动视图的界面,然后创建一个水平滚动视图(使用 iOS 17 中新的分页滚动)来显示用户可以在其之间横向滚动的多个子视图。到目前为止,它的行为完全符合我的要求,除了水平滚动视图中第一个视图的高度似乎设置了其他每个视图的高度,即使它们具有更高的内容。老实说,我不确定我想象中的行为是什么,但我想知道是否有人解决了类似的问题或以另一种方式设计了类似的布局。
这是一个最小的可重现示例:
import SwiftUI
struct ContentView: View {
@State private var selectedTab: String? = "Tab 1"
var body: some View {
ScrollView(.vertical) {
LazyVStack {
Image(systemName: "photo.fill")
.resizable()
.aspectRatio(contentMode: .fill)
ScrollView(.horizontal) {
LazyHStack(spacing: 0) {
SampleView(.purple, 5)
.id("Tab 1")
.containerRelativeFrame(.horizontal)
SampleView(.red, 12)
.id("Tab 2")
.containerRelativeFrame(.horizontal)
SampleView(.blue, 20)
.id("Tab 3")
.containerRelativeFrame(.horizontal)
}
.scrollTargetLayout()
}
.scrollPosition(id: $selectedTab)
.scrollTargetBehavior(.paging)
}
}
}
@ViewBuilder
func SampleView(_ color: Color, _ size: Int) -> some View {
LazyVGrid(columns: Array(repeating: GridItem(), count: 2), content: {
ForEach(1...size, id: \.self) { _ in
RoundedRectangle(cornerRadius: 15)
.fill(color.gradient)
.frame(height: 150)
}
})
}
}
从示例中可以看到,水平滚动视图的高度被锁定在第一个子视图的高度。
发生这种情况是因为
LazyHStack
用于水平滚动内容。外部 LazyVStack
的高度基于 LazyHStack
的初始高度,并且使用第一个子视图的高度,因为其他子视图不可见,因此尚未调整大小。
如果将
LazyHStack
更改为 HStack
,则垂直滚动将达到最高孩子的完整高度。当然,您也可以向下滚动到第一个孩子之外。您可能还想添加 .top
对齐:
ScrollView(.vertical) {
LazyVStack {
Image(systemName: "photo.fill")
// ...
ScrollView(.horizontal) {
HStack(alignment: .top, spacing: 0) { // 👈 HERE
// ...
}
.scrollTargetLayout()
}
.scrollPosition(id: $selectedTab)
.scrollTargetBehavior(.paging)
}
}