NEW BOOK! SwiftUI Fundamentals: The essential guide to SwiftUI core concepts and APIs. Learn more ...NEW BOOK! SwiftUI Fundamentals:Master SwiftUI core concepts and APIs. Learn more...

Defining custom scenes in SwiftUI

Scenes are a core concept in SwiftUI, representing containers for our app's user interface and behavior. They manage views, handle lifecycle events, and coordinate with the operating system. Understanding and leveraging scenes is crucial for organizing and maintaining complex applications.

SwiftUI provides several built-in scene types designed to cater to different needs and platforms. The most commonly used scene type is the WindowGroup, which defines the main window of an app and supports multiple windows on macOS and iPadOS. The DocumentGroup is ideal for document-based apps, providing built-in support for opening, editing, and saving documents. The Settings scene type is used to manage app settings, presenting a separate window on macOS. The Window scene creates a single unique window and is ideal for tools or utility panels.

One of the powerful features of SwiftUI is the ability to define custom scenes. Custom scenes allow us to create modular, maintainable code, making it easier to manage complex user interfaces.

To create a custom scene, we need to define a new struct that conforms to the Scene protocol. Here's an example of a custom scene that uses the Window type, which is available only on macOS:

#if os(macOS)
struct PanelScene: Scene {
    var body: some Scene {
        Window("Panel", id: "panel") {
            PanelView()
        }
    }
}
#endif

In this example, the PanelScene struct defines a scene that creates a window titled "Panel" and displays the PanelView within it. The #if os(macOS) compiler directive ensures that this code only compiles for macOS, making it suitable for multi-platform apps.

We can further customize the scene by observing the current phase using the scenePhase value from the environment. This allows us to perform actions based on the scene's state changes:

#if os(macOS)
struct PanelScene: Scene {
    @Environment(\.scenePhase) private var scenePhase
    
    var body: some Scene {
        Window("Panel", id: "panel") {
            PanelView()
        }
        .onChange(of: scenePhase) { _, newPhase in
            switch newPhase {
            case .active:
                print("Panel window is active")
            case .inactive:
                print("Panel window is inactive")
            default:
                break
            }
        }
    }
}
#endif

Once we have defined our custom scene, we can integrate it into the App struct's body. SwiftUI allows composing multiple scenes to create rich and versatile applications. Here’s how we can add the custom scene to the app:

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        
        #if os(macOS)
        PanelScene()
        #endif
    }
}

Scenes in SwiftUI offer a flexible and powerful way to structure and manage an app's user interface and behavior. By defining custom scenes, we can create modular and maintainable code tailored to specific use cases and platforms. This approach enhances our ability to build complex, multi-platform applications efficiently.

SwiftUI Fundamentals by Natalia Panferova book coverSwiftUI Fundamentals by Natalia Panferova book cover

Deepen your understanding of SwiftUI!$35

The essential guide to SwiftUI core concepts and APIs

SwiftUI Fundamentalsby Natalia Panferova

  • Explore the key APIs and design patterns that form the foundation of SwiftUI
  • Develop a deep, practical understanding of how SwiftUI works under the hood
  • Learn from a former Apple engineer who worked on widely used SwiftUI APIs

Deepen your understanding of SwiftUI!

The essential guide to SwiftUI core concepts and APIs

SwiftUI Fundamentals by Natalia Panferova book coverSwiftUI Fundamentals by Natalia Panferova book cover

SwiftUI Fundamentals

by Natalia Panferova

$35