SwiftUI.cc
Snippets
LayoutOther ModifiersAdvanced

SwiftUI PreferenceKey for Layout Measurement

Pass child measurements up the view tree with PreferenceKey when a parent needs information children know first.

6 min readUpdated 2026-06
Read child width
import SwiftUI

private struct WidthKey: PreferenceKey {
    static var defaultValue: CGFloat = 0
    static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
        value = max(value, nextValue())
    }
}

struct MeasuredTitle: View {
    @State private var width: CGFloat = 0

    var body: some View {
        Text("Overview")
            .background {
                GeometryReader { proxy in
                    Color.clear.preference(key: WidthKey.self, value: proxy.size.width)
                }
            }
            .onPreferenceChange(WidthKey.self) { width = $0 }
    }
}
Use this when

A parent view needs a child size, offset, or anchor to draw an overlay.

Children should publish layout information without direct bindings back to the parent.

You are building tabs, sticky headers, scroll indicators, or matched underlines.

Avoid this when

A simple binding would be clearer and does not create a layout feedback loop.

The measurement is static and can be expressed with frame constraints.

A custom Layout would centralize the behavior more cleanly.

Implementation notes

Preferences flow upward, which makes them a good fit for child-to-parent layout information.
The reduce function defines how multiple children combine their values.
Color.clear with GeometryReader is a common measuring pattern, but keep it contained.

Checklist

Avoid updating state in a way that causes endless layout changes.

Choose reduce behavior deliberately: max, sum, append, or last value.

Name keys for the information they publish.

Related reference