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
- Define and use a
WindowGroup
with an identifier. - Use the
openWindow
environment variable to open the window from another view. - 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:
@Environment(\.openWindow)
and@Environment(\.dismissWindow)
:- These environment variables provide the ability to open and close windows programmatically.
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.
- This
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"
.
- The first button uses
- This main view contains two buttons:
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.