How it works
PhysicalMetric is a property wrapper that resolves a real-world physical measurement into the point value SwiftUI needs to draw it at that true size. Because a point's relationship to physical length depends on the rendering surface and, in immersive contexts, on how far content sits from the viewer, you cannot hardcode a millimeter or inch value as points. Reach for PhysicalMetric when an element must measure a specific physical dimension regardless of device or distance, and let the wrapper read the environment and hand you a resolved CGFloat you apply like any other layout number.
Declare a resolved metric with @PhysicalMetric
Applying the wrapper to a stored property turns a physical measurement into a live, environment-resolved point value the wrapper recomputes as conditions change. You read the wrapped value as a plain number, exactly as the example reads its wrapped
iconSizestraight into a layout call rather than passing around the raw measurement.Specify the physical length you want
PhysicalMetric takes the real-world size to preserve, expressed in a physical unit, and converts it to points for the current surface. This is the conversion step the example sidesteps with a literal
44: PhysicalMetric instead lets you state the dimension physically so the drawn size stays correct after that conversion.Feed the resolved value into view modifiers
The point value coming out of the wrapper is an ordinary CGFloat, so it slots into any size-taking modifier. In the example the resolved number drives
.font(.system(size:))and could equally feed a.frame(width:height:), keeping the geometry in step with the wrapper's resolution.Let the environment drive recalculation
PhysicalMetric reads the surrounding environment to perform its conversion, so the same declaration yields different points across contexts without extra code. This is the same property-wrapper-watches-the-environment pattern the example shows with its scaled
iconSize, where the displayedInt(iconSize)updates as the environment shifts.
.font(.system(size: iconSize)), growing the ruler image to match the new real-world size.Example & preview
Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.
struct PhysicalMetricDemo: View {
@ScaledMetric var iconSize: CGFloat = 44
var body: some View {
HStack(spacing: 16) {
Image(systemName: "ruler")
.font(.system(size: iconSize))
.foregroundStyle(.blue)
VStack(alignment: .leading) {
Text("Scaled Size")
.font(.headline)
Text("\(Int(iconSize)) pt (Dynamic Type)")
.font(.caption)
.foregroundStyle(.secondary)
}
}
.padding()
}
}