swiftuiwindowvisionos

VisionOS window 3d position and rotation


I am playing with vision OS on simulator, and trying to make a virtual keyboard similar to the standard one (but with different buttons). I can make another WindowGroup in my app and fill it with buttons, and open it when app needs input.

However, I want this keyboard window to appear on similar position as the standard keyboard do (below main window), and in similar 3d rotation (as if "lying on the table", but not based on some physical object). How can I specify the position of newly opened window and its 3d rotation?

I expected there will be WindowGroup modifiers for that, but I can't find any.


Solution

  • Starting from Xcode 16, it supports creating new windows at custom position.

    A keyboard window is positioned directly below the main window.

        import SwiftUI
        
        @main
        struct YourAppName: App {
            @State
            private var mainWindow:WindowProxy?
            var body: some Scene {
                WindowGroup(id: "mainWindow") {
                    ContentView()
                }
                
                WindowGroup(id: "KeyboardWindow") {
                    KeyboardWindow()
                }
                .defaultSize(.init(width: 200, height: 100))
                .defaultWindowPlacement { content, context in
                    if let mainWindow = context.windows.first(where: { window in
                        return (window.id == "mainWindow")
                    }) {
                        return WindowPlacement(.below(mainWindow))
                    } else {
                        print("No window with ID 'mainWindow' found!")
                        return WindowPlacement()//use default placement if main window not exsist
                    }
                    
                }
           
             }
        }
        
        
        struct ContentView: View {
            @Environment(\.openWindow)
            var openWindowAction
            var body: some View {
                VStack {
        
                    Text("Hello, world!")
        
                    Button {
                        openWindowAction(id: "KeyboardWindow")
                    } label: {
                        Label("Open Keyboard", systemImage: "keyboard")
                    }
                    .buttonStyle(.bordered)
        
                }
                .padding()
            }
        }
        
        struct KeyboardWindow: View {
            var body: some View {
                Text("Here is keyboard window")
                    .padding(50)
            }
        }
        
        
        #Preview(windowStyle: .automatic) {
            Text("Preview does not support showing multiple window positioning.")
        }