Proportional Scaling in SwiftUI

Learn how to scale your SwiftUI views proportionally for different screen sizes on iPhone and iPad using UIScreen.main.bounds to create a responsive layout.

Proportional Scaling in SwiftUI

Note:

This tutorial explains how to create adaptive layouts in SwiftUI by setting view frames relative to the screen size, ensuring a consistent look across all devices.

Overview

When developing for iPhone and iPad models with different screen resolutions, you'll want to achieve a similar, if not identical, interface across all devices.

Assigning fixed-width and height values in your view's .frame() modifier is not suitable for creating a dynamic layout. To solve this, we will use the UIScreen.main.bounds.height and UIScreen.main.bounds.width properties to create proportional sizes.

Using UIScreen.main.bounds for Dynamic Sizing

UIScreen.main.bounds gives you the dimensions of the device's screen. You can then use these values to set the width and height of your views as a percentage of the screen size.

Here's an example of how to do this. We'll create a view with a Text element and an Image. While the Text has a static font size, the Image will be scaled based on the screen's dimensions.

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Proportional Scaling")
                .font(.largeTitle)
                .padding()

            Image("swiftui-logo")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(
                    width: UIScreen.main.bounds.width * 0.8,
                    height: UIScreen.main.bounds.height * 0.3
                )
        }
    }
}
Code for proportional scaling

In this code, the image's width is set to 80% of the screen's width, and its height is set to 30% of the screen's height.

The Result

By using this percentage-based evaluation, we aim to get similar results on different devices. Here is a comparison of how the layout looks on an iPhone 11 vs. an iPad Pro.

Comparison on different screen sizes

Note:

While UIScreen.main.bounds is useful, for more complex layouts in SwiftUI, it's often better to use a GeometryReader to get the size of the parent view, which provides more flexibility and avoids using a deprecated API in newer contexts (like multi-window iPad apps).