Dynamically Getting the View Size in SwiftUI

In a SwiftUI app, you can use GeometryReader to dynamically get the view size.

This article explains how to do it.

TOC

Output the View Size into the Console

Following the code, get the view size using GeometryReader and print it into the console.

struct ContentView: View {

    var body: some View {
        Text("Hello, world!")
            .padding()
            .background() {
                GeometryReader { geometry in
                    Path { path in
                        print("Text frame size = \(geometry.size)")
                    }
                }
            }
    }
}

This code prints the size of Text into the console as below.

Text frame size = (126.66666666666666, 52.33333333333333)

Place the GeometoryReader in the background

In SwiftUI, GeometryReader enables the view to get its size. So, you need to place the GeometryReader in the background of the view which you want to investigate the size by using the background modifier. SwiftUI resizes the background view to the same as the foreground view.

The geometry is a GeometryProxy structure. The GeometryProxy.size property has its view size.

You can also use Overlay

You can also use the overlay modifier instead of the background modifier to get the size with GeometryReader. You can choose one of them depending on the situation.

Example: Display into the Label

Let’s implement the code which displays the size into the Text instead of the console.

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))")
        }
    }
}

This code creates two labels. The lower ones display the size of the upper ones.

Example of displaying size on a label
Example of displaying size on a label

You can’t use the size while building views

This code assigns the getting size into the labelSize property, and the Text view displays the value of this property. This property has a @State attribute, so SwiftUI manages the labelSize property and contents of the Text view.

It’s crucial to be mindful of when you’re using GeometryReader to get the size, as the ContentView is still being built. If the labelSize property value changes, the ContentView needs to be rebuilt. However, it causes an error that changes the value while building. As a result, the Text view can’t display it.

If you run the code without DispatchQueue.main.async, the live preview of Xcode displays the value. Still, the iOS Simulator and the actual device can’t show the valid value.

0 x 0 is displayed in the iOS simulator or on the actual device.
0 x 0 is displayed in the iOS simulator or on the actual device.

Xcode also reports the error as below.

Error pointed out by Xcode
Error pointed out by Xcode

Modifying state during view update, this will cause undefined behavior.

This sample code employs the DispatchQueue.main.async method, which postpones property assignment until the view building is complete.

Worked on iOS simulator and real devices.
Worked on iOS simulator and real devices

Authored Books

Let's share this post !

Author of this article

Akira Hayashi (林 晃)のアバター Akira Hayashi (林 晃) Representative(代表), Software Engineer(ソフトウェアエンジニア)

アールケー開発代表。Appleプラットフォーム向けの開発を専門としているソフトウェアエンジニア。ソフトウェアの受託開発、技術書執筆、技術指導・セミナー講師。note, Medium, LinkedIn
-
Representative of RK Kaihatsu. Software Engineer Specializing in Development for the Apple Platform. Specializing in contract software development, technical writing, and serving as a tech workshop lecturer. note, Medium, LinkedIn

TOC