0

I'm working on a SwiftUI app for VisionOS, and I'd like to support multiple windows in my app to enhance the user experience. However, I couldn't find specific documentation or examples on how to achieve this for VisionOS.

In SwiftUI for iOS and iPadOS, we can create multiple windows using the .commands modifier with a CommandGroup for CommandGroupPlacement.newItem and then use WindowGroup to define the second window. However, when trying to apply the same approach in VisionOS, I encountered errors like "Value of type 'some Scene' has no member 'window'".

Is there a way to create multiple windows in a SwiftUI app for VisionOS? If so, how can I achieve this? Are there any specific APIs or modifiers I should use?

Any insights, code examples, or pointers to relevant documentation would be greatly appreciated.

Thank you!

János
  • 32,867
  • 38
  • 193
  • 353
  • Can you show which code produced this error? I've added multiple `WindowGroup(id: "SomeID")`s and opened them with `openWindow(id: "SomeID")` with the env value `@Environment(\.openWindow) private var openWindow` – fruitcoder Jul 31 '23 at 12:18

1 Answers1

0

Apple's Hello World project has great examples on how to open and dismiss different spaces. Here is an implementation of opening two windows programatically. Please note there are some issues with the latest versions of Xcode Beta which cause issues in the Hello World Application.

You need to add an ID for calling your second window:

import SwiftUI

@main
struct ExampleApp: App {
    var body: some Scene {
        WindowGroup {
            PrimaryWindow()
        }
        
        WindowGroup (id: "SecondWindow"){
            SecondWindow()
        }
    }
}

Then within the Primary window, declare the openWindow function:

@Environment(\.openWindow) private var openWindow
@Environment(\.dismissWindow) private var dismissWindow

This allows you to open a second window:

openWindow(id: "SecondWindow")

Full code below for PrimaryWindow and SecondWindow

import SwiftUI
import RealityKit
import RealityKitContent


struct PrimaryWindow: View {
    @Environment(\.openWindow) private var openWindow
    @Environment(\.dismissWindow) private var dismissWindow

    var body: some View {
           NavigationSplitView {
                       VStack {
                           Button(action: {
                               openWindow(id: "SecondWindow")
                               print("Show Second Window")
                           }) {
                               Text("Show Second Window")
                                   .font(.headline)
                                   .padding()
                                   .background(Color.blue)
                                   .foregroundColor(.white)
                                   .cornerRadius(10)
                           }
                           .buttonStyle(.plain)
                       }
                       .frame(maxWidth: .infinity, alignment: .top)
                   
               .navigationTitle("Sidebar")
           } detail: {
               Text("Detail")
           }
           
       }
   }

#Preview {
    PrimaryWindow()
}

SecondWindow

import SwiftUI
import RealityKit
import RealityKitContent

struct SecondWindow: View {
    @Environment(\.dismissWindow) private var dismissWindow

    var body: some View {
           NavigationSplitView {
               VStack {
                   Button(action: {
                       dismissWindow(id: "SecondWindow")
                       print("Show Second Window")
                   }) {
                       Text("Dismiss Second Window")
                           .font(.headline)
                           .padding()
                           .background(Color.blue)
                           .foregroundColor(.white)
                           .cornerRadius(10)
                   }
                   .buttonStyle(.plain)
               }
               .frame(maxWidth: .infinity, alignment: .top)
               .navigationTitle("Sidebar")
           } detail: {
               Text("Detail")
           }
           
       }
   }

#Preview {
    SecondWindow()
}

Zach
  • 1
  • 1
  • 9