XCode 14.3.1. Mac running Ventura 13.4.1. I have a clock app where the views are constrained to a 1 to 1 aspect ratio. The containing window however can be resized but has no aspect ratio constraints. The views stay correctly proportioned but it looks bad if say the window is tall and thin with a small view in it. This is a single window App so uses WindowGroup not NSWindow.
In the entry point code I can set the window max and min size like this
import SwiftUI
@main
struct Mac_TestApp: App {
var body: some Scene {
WindowGroup {
Overall_View()
.frame(minWidth: 300, idealWidth: 500, maxWidth: 600, minHeight: 300, idealHeight: 500, maxHeight: 600)
}
.windowResizability(.contentSize)
}
}
This sets the maximum and minimum size that the window width and height can be resized but does not fix the aspect ratio. The list of parameters I can change for WindowGroup is pretty short and does not have any aspect ratio that I can see (no AppDelegate in this type of App). I have seen examples of document apps where you override the NSWindow class and set your own window controller. This gives much more control but I have not seen anything similar for this type of app.
You could use Asperi‘s WindowAccessor
for this. The approach is described in this answer. It uses a NSViewRepresentable
to access the underlying NSWindow
.
import SwiftUI
struct WindowAccessor: NSViewRepresentable {
@Binding var window: NSWindow?
func makeNSView(context: Context) -> NSView {
let view = NSView()
DispatchQueue.main.async {
self.window = view.window // << right after inserted in window
}
return view
}
func updateNSView(_ nsView: NSView, context: Context) {}
}
So, in your case you could do the following:
@main
struct Mac_TestApp: App {
@State private var window: NSWindow?
var body: some Scene {
WindowGroup {
Overall_View()
.frame(minWidth: 300, idealWidth: 500, maxWidth: 600, minHeight: 300, idealHeight: 500, maxHeight: 600)
.background(WindowAccessor(window: $window))
.onChange(of: window) { newWindow in
newWindow?.contentAspectRatio = NSMakeSize(1, 1)
}
}
}
}
On a side note, for a single window app and development target macOS 13+, use Window
Scene instead of WindowGroup
.