Loading...

How to open and close windows programmatically in SwiftUI?

question swiftui macos
Ram Patra Published on September 3, 2024

To open or close a window programmatically from outside that window using environment variables, you need to leverage the new openWindow (macOS 13+) and dismissWindow (macOS 14+) environment variables. This environment variables allow you to programmatically open and close a window by its identifier.

Here’s how you can implement this:

Step-by-Step Example

  1. Define and use a WindowGroup with an identifier.
  2. Use the openWindow environment variable to open the window from another view.
  3. Use the dismissWindow environment variable to close the window from another view.

Example Implementation

import SwiftUI

@main
struct WindowExampleApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        
        WindowGroup("New Window") {
            NewWindowView()
        }
        .handlesExternalEvents(matching: ["newWindow"])
    }
}

struct ContentView: View {
    @Environment(\.openWindow) private var openWindow
    @Environment(\.dismissWindow) private var dismissWindow
    
    var body: some View {
        VStack {
            Button("Open New Window") {
                openWindow(id: "newWindow")
            }
            .padding()
            
            Button("Close New Window") {
                dismissWindow(id: "newWindow")
            }
            .padding()
        }
    }
}

struct NewWindowView: View {
    var body: some View {
        Text("This is a new window!")
            .frame(minWidth: 200, minHeight: 200)
            .padding()
    }
}

Explanation:

  1. @Environment(\.openWindow) and @Environment(\.dismissWindow):
    • These environment variables provide the ability to open and close windows programmatically.
  2. WindowGroup("New Window"):
    • This WindowGroup defines a window identified by "newWindow". The .handlesExternalEvents(matching: ["newWindow"]) allows this window group to be managed via external events like opening or closing.
  3. ContentView:
    • This main view contains two buttons:
      • The first button uses openWindow(id: "newWindow") to open a new window identified by "newWindow".
      • The second button uses dismissWindow(id: "newWindow") to close the window identified by "newWindow".
  4. NewWindowView:
    • This view is the content of the new window.

Running the App:

  • Opening the Window: Clicking the “Open New Window” button will open the new window with NewWindowView content.
  • Closing the Window: Clicking the “Close New Window” button will close the newly opened window using the dismissWindow environment variable.

This approach is more straightforward and leverages SwiftUI’s environment variables to manage windows without needing to manually track window references. It’s also more aligned with the declarative nature of SwiftUI.

If you’re curious to learn more ways to achieve the same, you can read this blog post.

Take your presentation to the next level.

Put your face and name on your screen.

Your to-dos on your menu bar.

Fill forms using your right-click menu.

Ram Patra Published on September 3, 2024
Image placeholder

Keep reading

If this article was helpful, others might be too

question swiftui macos September 3, 2024 Two ways to open a window programmatically in SwiftUI

SwiftUI provides an openWindow environment variable on macOS that allows you to open windows programmatically. Here’s how you can use it to open a new window when a button is clicked:

question swiftui swift October 30, 2023 How to convert Color type to hex and vice-versa while retaining alpha information?

The below should work both on macOS and iOS with one minor change. That is, use UIColor instead of NSColor if you’re planning to use it for iOS.

question swiftui swift September 30, 2023 How to open the Settings view in a SwiftUI app on macOS 14.0 (Sonoma)?

In macOS 14.0 (Sonoma), Apple removed support for NSApp.sendAction to open the Settings view in your SwiftUI app. You now have to use SettingsLink like below:

Like my work?

Please, feel free to reach out. I would be more than happy to chat.