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.

Presentify

Take your presentation to the next level.

FaceScreen

Put your face and name on your screen.

ToDoBar

Your to-dos on your menu bar.

Ram Patra Published on September 3, 2024
Image placeholder

Keep reading

If this article was helpful, others might be too

question swiftui March 6, 2023 How to render the icon on a menu bar as a template in SwiftUI?

Setting your app’s icon on the menu bar as a template makes it to adapt to light and dark modes automatically without you doing anything. To do this, you have to use this constructor of MenuBarExtra class.

question swiftui swift August 31, 2024 @StateObject vs @ObservedObject in SwiftUI

In SwiftUI, both @StateObject and @ObservedObject are property wrappers used to manage state in your views, specifically when working with objects that conform to the ObservableObject protocol. However, they serve slightly different purposes and have different use cases. Here’s a breakdown:

question swiftui swift September 7, 2024 How to apply mirroring to any SwiftUI view?

You can apply mirroring to a SwiftUI view by using the scaleEffect(x:y:anchor:) modifier to flip the view horizontally or vertically. Specifically, you can set the x or y scale to -1.0 to mirror the view along that axis.