Reading time: 1 min
This quick recipe shows how to measure a SwiftUI View, i.e get its size at runtime. This is useful when your layout depends on a particular view's dimensions.
So the trick is to embed a GeometryReader
in the view's background
or overlay
. The resulting GeometryProxy
's size will the that of the view itself:
myView
.background(GeometryReader { geometry in
Color.clear // stretches as much as it can and is invisible
})
If you wish to store the size in a State
var, the preferred way is to use view preferences:
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
struct MeasureSizeModifier: ViewModifier {
func body(content: Content) -> some View {
content.background(GeometryReader { geometry in
Color.clear.preference(key: SizePreferenceKey.self,
value: geometry.size)
})
}
}
extension View {
func measureSize(perform action: @escaping (CGSize) -> Void) -> some View {
self.modifier(MeasureSizeModifier())
.onPreferenceChange(SizePreferenceKey.self, perform: action)
}
}
Then, you can use it like this:
@State private var viewSize = CGSize.zero
var body: some View {
myView.measureSize {
viewSize = $0
}
}