I have a two Text
components inside a VStack
and I'm using GeometryReader
to match their widths.
The problem is if I apply padding
AFTER setting frame
to the Text
with the shorter content, I run into an infinite loop.
I want to understand why this is happening. My expectation is that it should just take the larger width and then apply padding to it.
import SwiftUI
struct ContentView: View {
@State private var containerWidth: CGFloat?
var body: some View {
VStack(alignment: .center) {
Text("Shorter Text")
.frame(width: containerWidth, alignment: .center)
.background { Color.green }
// this is `padding` is causing an infinite loop
.padding(.leading, 5)
Text("Really really long text")
.background {
Color.yellow
}
}
.background {
Color.red
}
.readSize { size in
containerWidth = size.width
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
extension View {
func readSize(onChange: @escaping (CGSize) -> Void) -> some View {
background(
GeometryReader { geometryProxy in
Color.clear
.preference(key: SizePreferenceKey.self, value: geometryProxy.size)
}
)
.onPreferenceChange(SizePreferenceKey.self, perform: onChange)
}
}
private struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {}
}
I tried switching around the application of padding
. This prevents the infinite recursion of width calculation but does not add the padding.