Skip to content

πŸͺŸ Easily present SwiftUI views in their own UIWindow

License

Notifications You must be signed in to change notification settings

divadretlaw/WindowKit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

faa2a95 Β· Feb 1, 2025

History

44 Commits
Sep 1, 2024
Feb 1, 2025
Feb 28, 2024
Oct 15, 2023
Apr 12, 2024
Feb 1, 2025
Feb 1, 2025
Mar 11, 2024

Repository files navigation

WindowKit

Handle UIWindow & UIWindowScene within SwifUI and present SwiftUI Views in their own window.

Usage

windowCover(isPresented:content:)

Static Badge

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
} 

Environment

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.

windowOverlay(content:)

Static Badge

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
} 

Static Badge

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

@Environment(\.window) var window

Static Badge

SwiftUI Lifecycle

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

UIKit Lifecycle

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

@Environment(\.windowScene) var windowScene

The @Environment(\.windowScene) var windowScene defaults to the first connected UIWindowScene or nil if no UIWindowScene is connected.

License

See LICENSE