|
import SwiftUI |
|
import Observation |
|
import os |
|
|
|
/// A trick in SwiftUI to have a singls shared global window. |
|
/// We want the user to be able to show and hide this window, and change the content in it. Hitting show multiply times should NOT open multiple windows but instead should bring the shared window forward. |
|
/// The trick is to use a dummy Singleton type (here we embed it with the shared content) that we can pass to open/dismissWindow and the WindowGroup. The dummy SIngleton type must contain no properties and merely exists to trick SwiftUI into only ever showing one window for the type at a time. |
|
|
|
@Observable |
|
class SharedContent { |
|
struct Singleton: Hashable, Codable { |
|
} |
|
|
|
var isWindowVisible = false |
|
var content: String = "my lovely horse" |
|
} |
|
|
|
@main |
|
struct WindowTestApp: App { |
|
@State |
|
var sharedContent = SharedContent() |
|
|
|
var body: some Scene { |
|
WindowGroup("Main") { |
|
ContentView(sharedContent: sharedContent) |
|
} |
|
.environment(sharedContent) |
|
WindowGroup("Document", for: SharedContent.Singleton.self) { _ in |
|
DocumentView() |
|
} |
|
.environment(sharedContent) |
|
} |
|
} |
|
|
|
struct ContentView: View { |
|
@Environment(\.openWindow) |
|
var openWindow |
|
|
|
@Environment(\.dismissWindow) |
|
var dismissWindow |
|
|
|
@Bindable |
|
var sharedContent: SharedContent |
|
|
|
var body: some View { |
|
TextField("Content", text: $sharedContent.content) |
|
Button("Show") { |
|
// We rely on the `onChange(of:)` to do the actual opening/closing. Which is a bit janky but for purposes of demo… |
|
sharedContent.isWindowVisible = true |
|
} |
|
Button("Dismiss") { |
|
sharedContent.isWindowVisible = false |
|
} |
|
Toggle("Window Visible", isOn: $sharedContent.isWindowVisible) |
|
.toggleStyle(.button) |
|
.onChange(of: sharedContent.isWindowVisible) { |
|
if sharedContent.isWindowVisible { |
|
print("Open window") |
|
openWindow(value: SharedContent.Singleton()) |
|
} |
|
else { |
|
dismissWindow(value: SharedContent.Singleton()) |
|
} |
|
} |
|
} |
|
} |
|
|
|
struct DocumentView: View { |
|
@Environment(SharedContent.self) |
|
var sharedContent |
|
|
|
var body: some View { |
|
Text(verbatim: "\(sharedContent.content)") |
|
.onAppear { |
|
sharedContent.isWindowVisible = true |
|
} |
|
.onDisappear { |
|
sharedContent.isWindowVisible = false |
|
} |
|
} |
|
} |