在SwiftUI中,我发现一个问题,就是在原有的视图上添加ScrollView,就会导致高度被压缩。

通过对比,可以看到,当添加ScrollView后,VStack的宽度没有变化,但是高度被明显压缩。
在实际应用中也是如此。

根据实际应用的对比,可以查看到,当VStack外层添加ScrollView后,显示的视图高度减少了。
经过对比发现,实际是Spacer()不再自动填充内容的区域,因此如果Spacer()不设置frame的高度,则默认为空。

当给Spacer()设置frame后,高度得到填充。
因此,在 ScrollView 里面的 VStack,如果不设置 height,它的高度会自动根据内容的高度自适应。
特殊机制
在ScrollView 里面有个特殊的机制:
ScrollView 会限制子视图的高度,如果 VStack 的高度不固定,ScrollView 会认为它的内容高度是「不确定的」,因此:
高度取决于 VStack 内部内容的高度。
如果内容不足以填充整个 ScrollView,那么 ScrollView 只会占据内容高度,导致它无法占满父容器的高度。
ScrollView 的工作原理
ScrollView 会根据子视图的尺寸自动调整。
如果 VStack 不设置 height,它的高度会根据内部内容自动计算。
但当内容高度小于 ScrollView 的高度时,ScrollView 的高度不会被撑满,会变成「内容高度」的大小。
解决办法
给 VStack 一个固定的 height,保证 ScrollView 可以填充整个父容器。
GeometryReader { geometry in
let width = geometry.size.width
let height = geometry.size.height
ScrollView {
VStack {
Text("Hello World")
Text("This is a test")
}
.frame(width: width,height: height) // 高度固定,ScrollView 会占满父容器
}
}
ScrollView 会填充整个父容器的高度。
即使 VStack 内部内容较少,ScrollView 也会占满 height 设定的高度,Spacer()也可以占用剩余的空间。

总结
VStack 的 height 需要手动设置,因为 ScrollView 需要一个明确的高度来决定它占据多少空间。
没有 height 时,ScrollView 会根据内容高度决定大小,这在内容少时会导致高度不够撑满。