TechnologiesSwiftUI

WindowProxy struct

iOSmacOStvOSwatchOSvisionOS✓ renders

The proxy for an open window in the app.

How it works

A WindowProxy is a lightweight handle that SwiftUI hands you for an individual window in a scene, letting you read and act on that window without owning a reference to the underlying platform object. It bridges the gap between SwiftUI's declarative scene tree and the imperative act of opening, locating, or dismissing a specific window at runtime. Reach for it when a window's identity matters — when you present an auxiliary window such as an inspector or palette and later need to bring it forward or close it from elsewhere in your interface.

  1. Acquire window actions from the environment

    You rarely construct a WindowProxy yourself; instead you obtain the actions that operate on windows from the environment. Read openWindow via @Environment(\.openWindow) and dismissWindow via @Environment(\.dismissWindow) so the view can drive window lifecycle from inside its body.

  2. Open a window by its scene identifier

    Calling the openWindow action with an id presents the matching scene and resolves to the corresponding window, surfacing it as a WindowProxy to the scene that declares it. Here openWindow(id: "inspector") opens the window whose scene is registered under that identifier, creating it if it isn't already on screen.

  3. Dismiss the same window by identity

    The counterpart dismissWindow action closes a window addressed by the same key, so the proxy's identity is what ties the two calls together. dismissWindow(id: "inspector") tears down the window opened above, leaving other scenes untouched.

  4. Keep identifiers in sync with the scene declaration

    Because a WindowProxy is resolved through a string id, that identifier must match the Window or WindowGroup scene you declared in your App. The "inspector" string passed to both openWindow and dismissWindow is the contract that lets SwiftUI locate the right window to act on.

Try it — Change the id passed to dismissWindow(id: "inspector") to a different string and confirm the Dismiss Inspector button no longer closes the window, since the proxy can only act on the window whose identifier it names.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

WindowProxy.swift
struct WindowProxyDemo: View {
    @Environment(\.openWindow) private var openWindow
    @Environment(\.dismissWindow) private var dismissWindow

    var body: some View {
        VStack(spacing: 16) {
            Text("Window Control")
                .font(.headline)
            Button("Open Inspector") {
                openWindow(id: "inspector")
            }
            .buttonStyle(.borderedProminent)
            Button("Dismiss Inspector") {
                dismissWindow(id: "inspector")
            }
            .buttonStyle(.bordered)
        }
        .padding()
    }
}
Live preview
Window Control Open Inspector Dismiss Inspector
Window Control Open Inspector Dismiss Inspector
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →