Search code examples
swiftmacoswindowswiftui

How do I set a minimum size for a window and make it use the specified size and position when launching?


I am making a MacOS app with the default SwiftUI Application template. How can I set the minimum size of the window to (800, 500)? Also if I close the window, and reopen, it reopens as the size and position from when it last closed. How do I make it not remember the window position and size from when it last closed? I am using Xcode 11.2.1 and MacOS Catalina. How can I do these?


Solution

  • If you created project from template for macOS SwiftUI based, then all changes you need to do is in AppDelegate.swift.

    The size of window is content-defined, so you need to specify root content view frame, and to disallow window position saving you need to remove setFrameAutosaveName, as a result your AppDelegate should look like the following

    @NSApplicationMain
    class AppDelegate: NSObject, NSApplicationDelegate {
    
        var window: NSWindow!
    
        func applicationDidFinishLaunching(_ aNotification: Notification) {
            // Create the SwiftUI view that provides the window contents.
            let contentView = ContentView()
                .frame(minWidth: 800, maxWidth: .infinity, minHeight: 500, maxHeight: .infinity)
    
            // Create the window and set the content view. 
            window = NSWindow(
                contentRect: NSRect(x: 0, y: 0, width: 800, height: 500),
                styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
                backing: .buffered, defer: false)
            window.center()
            window.contentView = NSHostingView(rootView: contentView)
            window.makeKeyAndOrderFront(nil)
        }
        ...
    

    Update: for SwiftUI life-cycle approach is the same - set frame to content view in window scene, like

    var body: some Scene {
        WindowGroup {
            ContentView()
                .frame(minWidth: 800, maxWidth: .infinity, minHeight: 500, maxHeight: .infinity)
        }
    }