You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VisionOS中创建视觉分离且相对主窗口定位的视图的推荐方案

VisionOS 实现与主窗口分离且保持相对位置的视图方案

推荐方案一:辅助窗口 + 空间锚定(完全独立场景)

适合需要独立生命周期、单独交互的复杂视图,通过监听主窗口空间位置,同步辅助窗口的3D坐标:

  1. 在App结构体中声明主窗口和辅助窗口组:
@main
struct YourVisionApp: App {
    @State private var auxiliaryWindowActive = false
    @State private var mainWindowPos: SIMD3<Float> = .zero

    var body: some Scene {
        // 主窗口
        WindowGroup {
            MainContentView()
                .onChange(of: UIApplication.shared.connectedScenes) { scenes in
                    // 实时获取主窗口的空间位置
                    guard let mainScene = scenes.first(where: { $0 is UIWindowScene }) as? UIWindowScene,
                          let mainWindow = mainScene.windows.first else { return }
                    mainWindowPos = mainWindow.sceneSpace.position
                }
                .toolbar {
                    Button("打开悬浮视图") {
                        auxiliaryWindowActive = true
                    }
                }
        }

        // 辅助窗口(分离视图)
        WindowGroup(id: "detached-view") {
            DetachedComplexView()
                .windowStyle(.plain) // 移除默认窗口装饰
                .onAppear {
                    guard let auxScene = UIApplication.shared.connectedScenes.first(where: {
                        $0.session.configuration.name == "detached-view"
                    }) as? UIWindowScene, let auxWindow = auxScene.windows.first else { return }
                    // 设置相对于主窗口的偏移位置(示例:右下方)
                    auxWindow.sceneSpace.position = mainWindowPos + SIMD3<Float>(0.5, -0.3, 0)
                    // 自定义窗口尺寸
                    auxWindow.sceneSpace.size = SIMD2<Float>(0.6, 0.4)
                }
        }
        .windowResizability(.contentSize)
        .defaultSize(CGSize(width: 600, height: 400))
    }
}
  1. 主窗口移动时,onChange会更新主窗口位置,辅助窗口可通过监听mainWindowPos的变化,实时同步自身坐标。

推荐方案二:主窗口内悬浮分层视图(轻量视觉分离)

如果不需要独立窗口生命周期,仅需视觉上与主内容分离,直接在主窗口内用ZStack结合3D偏移实现:

struct MainContentView: View {
    var body: some View {
        ZStack {
            // 主窗口核心内容
            Text("主窗口内容区域")
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .background(Color.white)

            // 分离的复杂视图
            VStack(spacing: 20) {
                Text("复杂悬浮视图标题")
                    .font(.title)
                Button("功能按钮") {}
                Image(systemName: "gearshape.fill")
                    .font(.largeTitle)
                // 可添加任意复杂UI元素
            }
            .frame(width: 320, height: 450)
            .background(Color.gray.opacity(0.9))
            .cornerRadius(16)
            .shadow(color: .black.opacity(0.3), radius: 12, x: 0, y: 6)
            // 相对主窗口的2D位置(右侧居中)
            .position(x: UIScreen.main.bounds.width - 180, y: UIScreen.main.bounds.height / 2)
            // 3D偏移增强分离感
            .offset(z: 60)
        }
        .containerBackground(for: .window) {
            Color.clear
        }
    }
}

这种方案无需处理多窗口逻辑,视图会随主窗口一起移动,定位和尺寸完全自定义,适合大部分复杂UI的视觉分离需求。

方案对比

  • 方案一:完全独立窗口,有自己的场景生命周期,适合需要单独后台运行、独立交互的场景,但需要手动同步位置。
  • 方案二:轻量实现,无多窗口复杂度,适合仅需视觉分离的场景,布局灵活可控。

注意:避免使用bottomOrnament修饰符,它专为工具栏设计,尺寸和位置限制较多,无法满足复杂大视图的需求。

内容的提问来源于stack exchange,提问作者Kaven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:46:08