Handle UIWindow
& UIWindowScene
within SwifUI and present SwiftUI Views in their own window.
Important
Keep in mind that the content is detached from the host view, as it lives in its own context.
This means in order to pass data between the host view and the content in the window, you need to use
a model to communicate. For example by using anObservableObject
.
Present a modal view within it's own UIWindow
from any SwiftUI view.
Usage is similar to fullscreenCover(isPresented:content:)
.windowCover(isPresented: $isPresented) {
MyWindowCover()
}
You can also configure the window presentation
.windowCover(isPresented: $isPresented) {
MyWindowCover()
} configure { configuration in
// Customize the window cover presentation
}
In order to dismiss the window cover, use the dismissWindowCover
from the environment
@Environment(\.dismissWindowCover) var dismiss
In case the current view is not presented within a window cover the dismissWindowCover
action will do nothing.
Present a modal view within it's own UIWindow
from any SwiftUI view.
Usage is similar to overlay(content:)
.windowOverlay {
MyWindowOverlay()
}
You can also configure the window presentation
.windowOverlay {
MyWindowOverlay()
} configure { configuration in
// Customize the window overlay presentation
}
Read the current UIWindow
or NSWindow
with WindowReader
@main
struct MyView: View {
var body: some Scene {
WindowReader { window in
...
}
}
}
On child views the UIWindow
or NSWindow
will be available in the Environment
@Environment(\.window) var window
Read the current UIWindowScene
with WindowSceneReader
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
WindowSceneReader { windowScene in
ContentView()
}
}
}
}
alternatively, just add windowScene()
if you only need the window scene on child views.
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.windowScene()
}
}
}
On child views the UIWindowScene
will be available in the Environment
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let rootView = ContentView()
.windowScene(windowScene)
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: rootView)
self.window = window
window.makeKeyAndVisible()
}
}
@Environment(\.windowScene) var windowScene
The @Environment(\.windowScene) var windowScene
defaults to the first connected UIWindowScene
or nil
if no UIWindowScene
is connected.
See LICENSE