ramnefors
ramnefors

Reputation: 73

SwiftUI window size for document based MacOs App

I am moving my app from SwiftUI xCode 11 to the new Document Based App lifecycle format in xCode 12. I have not been able to figure out how to set the window size. In Xcode 11 I had

window = NSWindow(
            contentRect: NSRect(x: 0, y: 0, width: 1200, height: 800),
            styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
            backing: .buffered, defer: false)

How do I achieve the same effect with no AppDelegate?

Upvotes: 7

Views: 3791

Answers (3)

Rick
Rick

Reputation: 3877

In macOS 13.0.1, this works:

    var
    body: some Scene
    {
        DocumentGroup(newDocument: MyDocument())  //  Or WindowGroup
        { file in
            ContentView(document: file.$document)
        }
        .defaultSize(width: 200, height: 400)     //  <-- Set your default size here.
    }

Note that app state restoration might confuse matters, but creating a new document (or deleting app state) should create a new window with the specified default.

Upvotes: 5

Jury Shortki
Jury Shortki

Reputation: 181

I used the trick of swapping out the minimum size. It's not elegant, but it solves the problem.

struct ContentView: View
{
    @ObservedObject var document: MyDocument

    @State var minSize:CGSize = {
        // Set your preferred initial size here
        guard let screen = NSScreen.main?.frame.size
        else { return CGSize(width: 800, height: 600) }
        return CGSize(width: screen.width * 0.75, height: screen.height * 0.75)
    }()
    
    var body: some View
    {
        VStack
        {
            Text("Content")
        }
        .frame(minWidth: minSize.width, minHeight: minSize.height)
        .onAppear {
            Task {
                await Task.sleep(500_000_000)
                // Set your real min size here
                minSize = CGSize(width: 600, height: 400)
            }
        }
    }
}

I hope the next SwiftUI will have a normal way.

Upvotes: 0

Asperi
Asperi

Reputation: 258551

Try the following (as window by default has .fullSizeContentView)

var body: some Scene {
    WindowGroup {
        ContentView()
          .frame(width: 1200, height: 800)    // << here !!
          .frame(minWidth: 800, maxWidth: .infinity, 
               minHeight: 600, maxHeight: .infinity)
    }
}

Upvotes: 2

Related Questions