Skip to content

Instantly share code, notes, and snippets.

@schwa
Created December 15, 2023 19:28
Show Gist options
  • Save schwa/adf90be71288250edb52db98fc49eba4 to your computer and use it in GitHub Desktop.
Save schwa/adf90be71288250edb52db98fc49eba4 to your computer and use it in GitHub Desktop.
SwiftUI example showing how to make a Shared Content Window…
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
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment