I want to use a ScrollView outside of a VStack, so that my content is scrollable if the VStack expands beyond screen size.
Now I want to use GeometryReader
within the VStack and it causes problems, which I can only solve by setting the GeometryReader frame, which does not really help me given that I use the reader to define the view size.
Here is the code without a ScrollView and it works nicely:
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)
}
}
This results in the following image:
The custom sized label should be full width, but half the width for height. Now if I wrap the same code in a ScrollView, this happens:
Not just did everything get smaller, but the height of the Custom Sized Label is somehow ignored. If I set the height of the GeometryReader, I can adjust that behaviour, but I want to GeometryReader to grow as large as its content. How can I achieve this?
Thanks
It should be understood that
GeometryReader
is not a magic tool, it just reads available space in current context parent, but...ScrollView
does not have own available space, it is zero, because it determines needed space from internal content... so usingGeometryReader
here you have got cycle - child asks parent for size, but parent expects size from child... SwiftUI renderer somehow resolves this (finding minimal known sizes), just to not crash.Here is possible solution for your scenario - the appropriate instrument here is view preferences. Prepared & tested with Xcode 12 / iOS 14.
Note: ... and don't use GeometryReader if you are not sure about context in which your view is.