user12498286
user12498286

Reputation:

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?

Upvotes: 16

Views: 11651

Answers (2)

Asperi
Asperi

Reputation: 257523

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

Upvotes: 23

RobMac
RobMac

Reputation: 860

Newer versions of Xcode (and template) now use SwiftUI App life cycle, as opposed to the AppKit App Delegate. In that case, you case can set the window size (or the size of any SwiftUI View) using the Layout.frame method to setup your boundaries. Just like you would with any modifier:

    VStack {
        Text("You are Logged In")
        Button(action: {
            self.loggedIn = false
        }, label: {
            Text("Logout")
        })
    }
    .frame(minWidth: 400, idealWidth: 600, minHeight: 450, idealHeight: 800)

Again, this can be used with any SwiftUI View, so it's a handy way to layout your views.

Edit: This answer applies to all platforms, including macOS.

Upvotes: 9

Related Questions