SwiftUI ScrollView VStack GeometryReader高度已忽略
我想在VStack之外使用滚动视图,这样,如果VStack扩展到屏幕大小以外,我的内容就可以滚动。 现在我想在VStack中使用SwiftUI ScrollView VStack GeometryReader高度已忽略,swiftui,geometryreader,Swiftui,Geometryreader,我想在VStack之外使用滚动视图,这样,如果VStack扩展到屏幕大小以外,我的内容就可以滚动。 现在我想在VStack中使用GeometryReader,这会导致问题,我只能通过设置GeometryReader框架来解决,这对我没有帮助,因为我使用阅读器来定义视图大小 下面是没有滚动视图的代码,它工作得很好: struct MyExampleView: View { var body: some View { VStack { Text("Top Lab
GeometryReader
,这会导致问题,我只能通过设置GeometryReader框架来解决,这对我没有帮助,因为我使用阅读器来定义视图大小
下面是没有滚动视图的代码,它工作得很好:
struct MyExampleView: View {
var body: some View {
VStack {
Text("Top Label")
.background(Color.red)
GeometryReader { reader in
Text("Custom Sized Label")
.frame(width: reader.size.width, height: reader.size.width * 0.5)
.background(Color.green)
}
Text("Bottom Label")
.background(Color.blue)
}
.background(Color.yellow)
}
}
这将产生下图:
自定义大小的标签应为全宽,但高度为半宽。
现在,如果在ScrollView中包装相同的代码,则会发生以下情况:
不仅所有的东西都变小了,定制尺寸标签的高度也被忽略了。
如果我设置GeometryReader的高度,我可以调整该行为,但我希望GeometryReader的增长与其内容一样大。我怎样才能做到这一点
谢谢应该理解的是,
GeometryReader
不是一个神奇的工具,它只是读取当前上下文中的可用空间,但是<代码>滚动视图没有自己的可用空间,它为零,因为它从内部内容确定所需的空间。。。因此,使用GeometryReader
这里您得到了cycle-child请求父级提供大小,但父级希望子级提供大小。。。SwiftUI渲染器以某种方式解决了这个问题(找到最小的已知大小),只是为了不崩溃
以下是适用于您的场景的可能解决方案-适当的工具是视图首选项。使用Xcode 12/iOS 14进行准备和测试
注:。。。如果您不确定视图所在的上下文,请不要使用GeometryReader。谢谢!首选项值精确设置在哪里?如果将初始值设置为0,则视图高度为0。如果我将其设置为10,则为10。请参阅添加的更多注释,查看首选项在同一渲染周期内将值从子级传递到父级。谢谢!奇怪的是,这样对我不起作用。似乎没有调用onPreferenceChanged。我会努力的。
struct DemoLayout_Previews: PreviewProvider {
static var previews: some View {
Group {
MyExampleView()
ScrollView { MyExampleView() }
}
}
}
struct MyExampleView: View {
@State private var height = CGFloat.zero
var body: some View {
VStack {
Text("Top Label")
.background(Color.red)
Text("Custom Sized Label")
.frame(maxWidth: .infinity)
.background(GeometryReader {
// store half of current width (which is screen-wide)
// in preference
Color.clear
.preference(key: ViewHeightKey.self,
value: $0.frame(in: .local).size.width / 2.0)
})
.onPreferenceChange(ViewHeightKey.self) {
// read value from preference in state
self.height = $0
}
.frame(height: height) // apply from stored state
.background(Color.green)
Text("Bottom Label")
.background(Color.blue)
}
.background(Color.yellow)
}
}
struct ViewHeightKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue = CGFloat.zero
static func reduce(value: inout Value, nextValue: () -> Value) {
value += nextValue()
}
}