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

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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