Loading...

How to open a new window in SwiftUI?

question swift swiftui
Ram Patra Published on May 29, 2022

Although many things in SwiftUI are idiomatic and straightforward, showing your view in a new window needs a bit of coding to do. Hence, this short post.

First, let’s create a Window Controller that will hold your window/view:

import AppKit
import SwiftUI

class WindowController<RootView: View>: NSWindowController {
    convenience init(rootView: RootView) {
        let hostingController = NSHostingController(rootView: rootView.frame(width: 400, height: 400))
        let window = NSWindow(contentViewController: hostingController)
        window.setContentSize(NSSize(width: 400, height: 400))
        self.init(window: window)
    }
}

What we’re doing here is creating a Hosting Controller (which is a subclass of View Controller) that takes your supplied View, does its magic, and then gives it to NSWindow.

Now, let’s create two Views in SwiftUI, Parent and Child, like below:

import SwiftUI

struct NewWindowParentView: View {
    @State private var windowCount = 1
    
    var body: some View {
        Button("Show new window") {
            let windowController = WindowController(rootView: NewWindowChildView())
            windowController.window?.title = "Child Window \(windowCount)"
            windowCount += 1
            windowController.showWindow(nil)
        }
    }
}
import SwiftUI

struct NewWindowChildView: View {
    var body: some View {
        Text("Child view")
    }
}

Parent View resemble whatever your main View in your app is and the Child View is the View that you want to show in a new Window.

That’s it. So, when you open the Parent View, you will see a Button and every time you press this button, a new Window will be created showing your Child View.

Lastly, the entire example code can be found on GitHub.

Ram Patra Published on May 29, 2022
Image placeholder

Keep reading

If this article was helpful, others might be too

question macOS swift August 6, 2020 How to keep an app's window always on top of others in Swift?

Before launching the window, just use the appropriate window level, and you’re done.

question swift August 9, 2020 How to iterate an array in reverse in Swift?

From Swift 5.0, you can use any of the following approaches to iterate an array in reverse.

question macOS swift March 14, 2021 How to ignore mouse events in a view or window in macOS?

You can ignore mouse events in a window/view by adding just a single line of code.