To get the size of the view dynamically while the app is running in SwiftUI, use GeometryReader
.
This article explains the specific method and code examples.
Outputs the view size into the console
To get the view size with GeometryReader
, write as follows.
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.padding()
.background() {
GeometryReader { geometry in
Path { path in
print("Text frame size = \(geometry.size)")
}
}
}
}
}
When this code is executed, the size of the Text
is output to the console as follows.
Text frame size = (126.66666666666666, 52.33333333333333)
Place GeometryReader in the background
The view that can know its own size in SwiftUI is the GeometryReader
. So, using the background
modifier, place the GeometryReader
in the view whose size you want to get.
geometry
is a GeometryProxy
structure; the GeomertyProxy.size
property contains the size of the view.
You can also use overlay
You can use the overlay
modifier instead of the background
modifier to get the size in the same way. It is a good idea to use different modifiers depending on the situation.
Implementation example, Display on label
Let’s implement the code we actually used. Let’s implement the code to display the value in a separate Text
instead of outputting it to the console. The code will look something like this.
struct ContentView: View {
@State private var labelSize: CGSize = CGSize()
var body: some View {
VStack {
Text("Hello, world!")
.padding()
.background() {
GeometryReader { geometry in
Path { path in
let size = geometry.size
DispatchQueue.main.async {
if self.labelSize != size {
self.labelSize = size
}
}
}
}
}
Text("Label Size : \(String(format: "%.0f x %.0f", labelSize.width, labelSize.height))")
}
}
}
When this code is executed, two labels are displayed as follows, with the size of the upper label displayed on the lower label.

Cannot change view contents using size retrieved during view construction
In order to display the acquired size in Text
, the acquired size is assigned to the labelSize
property. Since we want to use this value to change the display content of Text
, we add a @State
attribute to let SwiftUI manage the labelSize
.
It is important to note that the moment the view size is obtained by the GeometryReader
, the view is still in the construction; if the labelSize
property is changed, the view must be rebuilt. If the labelSize
property is changed while the view is being rebuilt, it cannot be rebuilt, an error occurs, and the text cannot be displayed using the acquired value.
When I actually do this, it works in Xcode’s live preview, but when I run it in the iOS simulator or on an actual device, it does not show the size.

The following error message also appears in Xcode when run on an iOS simulator or actual device.

Modifying state during view update, this will cause undefined behavior.
Therefore, we use the DispatchQueue.main.async
method to have the property assigned a value after the rebuilding process is complete. When the property is updated, the view is rebuilt.
