I'd like to ask you some help. I'm trying to capture VStack height using geometry and then based on that VStack height value, calculate its child element's height (inside VStack).
Image of my current view of VStack
I used .frame outside of VStack to fill the whole screen. Then I used .border to visually check if it actually fills the screen (it works fine)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: Alignment.topLeading)
The problem can be seen inside the VStack, the height is displayed as GCFloat 734. Even though the border size is a lot bigger.
struct BodyView: View {
@State var stackHeight : CGFloat = 0
var body: some View {
GeometryReader { geometry in
VStack {
Text("VStack size: \(self.stackHeight)")
.bold()
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal)
.background(Color.green)
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: Alignment.topLeading)
.onAppear{
self.stackHeight = geometry.size.height
}
.border(Color.purple, width: 5)
}
}
}
struct BodyView_Previews: PreviewProvider {
static var previews: some View {
BodyView()
}
}
How could I capture the actual size of the VStack when it finishes loading?
When I trigger (onAppear) the VStack height appears correct, however I need it to be captured instantly.
If I understand your questions, you're very close — you just need to use to GeometryProxy
type:
import SwiftUI
struct BodyView: View {
var body: some View {
GeometryReader { geometry in
VStack {
Text("VStack size: \(geometry.size.height)") // no need for state var anymore
.bold()
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal)
.background(Color.green)
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: Alignment.topLeading)
.border(Color.purple, width: 5)
}
}
}
struct BodyView_Previews: PreviewProvider {
static var previews: some View {
BodyView()
}
}
A GeometryReader
will lay itself out again if its size changes.