Fixed aspect ratio in VisionOS view

By default, user can resize the spatial views however they like, which can lead to incorrect UI. Is it possible to set a specific aspect ratio, for example, 16/9?

I tried using .aspectRatio() on the SwiftUI view, in combination with .windowResizability(.contentSize) on the WindowGroup, but it didn't work.

One more idea was to use GeometryReader to dynamically calculate the width and height for a specific aspect ratio and then set the proper maxHeight and maxWidth in the frame, but it also didn't work.

There's no documentation about it and Apple's sample apps don't have it as well. But I've seen some apps (even some of the standard ones like Apple TV) having a fixed ratio, would really appreciate if somebody could help with this!

Answered by Matt Cox in 779429022

Hi @alexvznk,

This can't be solved with SwiftUI alone, but can be achieved by setting the resizing restriction preference on the UIWindowScene using requestGeometryUpdate(_:errorHandler:)

For example, this will app will have a default size of 1920x1080, and resizing will be restricted to the 16:9 aspect ratio.

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            Color.red
                .onAppear {
                    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
                        return
                    }
						
                    windowScene.requestGeometryUpdate(.Vision(resizingRestrictions: UIWindowScene.ResizingRestrictions.uniform))
                }
        }
            .defaultSize(width: 1920, height: 1080)
    }
}

You can see this API being used in the Happy Beam sample code from WWDC 23.

Accepted Answer

Hi @alexvznk,

This can't be solved with SwiftUI alone, but can be achieved by setting the resizing restriction preference on the UIWindowScene using requestGeometryUpdate(_:errorHandler:)

For example, this will app will have a default size of 1920x1080, and resizing will be restricted to the 16:9 aspect ratio.

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            Color.red
                .onAppear {
                    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
                        return
                    }
						
                    windowScene.requestGeometryUpdate(.Vision(resizingRestrictions: UIWindowScene.ResizingRestrictions.uniform))
                }
        }
            .defaultSize(width: 1920, height: 1080)
    }
}

You can see this API being used in the Happy Beam sample code from WWDC 23.

Thank you a lot! Exactly what I was looking for!

Fixed aspect ratio in VisionOS view
 
 
Q