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

VisionOS中创建跟随主窗口的无关闭控件侧边窗口

VisionOS 主窗口+跟随侧边窗口实现方案

你的代码存在的问题

  1. 两个WindowGroup不会自动同时显示,用户需要手动通过应用菜单或切换器打开第二个窗口;
  2. 没有设置侧边窗口的位置跟随逻辑;
  3. 没有隐藏侧边窗口的关闭控件。

修复方案及完整代码

第一步:更新AppState跟踪主窗口位置

import SwiftUI
import UIKit

class AppState: ObservableObject {
    @Published var mainWindowFrame: CGRect = .zero
    
    // 更新侧边窗口位置
    func updateSideWindowPosition() {
        guard let sideWindow = UIApplication.shared.windows.first(where: {
            $0.windowScene?.session.configuration.name == "side"
        }) else { return }
        
        let gap: CGFloat = 20 // 主窗口与侧边窗口的间距
        let sideWindowWidth: CGFloat = 300 // 侧边窗口宽度
        
        sideWindow.frame = CGRect(
            x: mainWindowFrame.origin.x + mainWindowFrame.width + gap,
            y: mainWindowFrame.origin.y,
            width: sideWindowWidth,
            height: mainWindowFrame.height
        )
    }
}

第二步:修改App结构体实现自动打开+位置同步

@main
struct YourAppName: App {
    @StateObject private var appState = AppState()
    @Environment(\.openWindow) private var openWindow
    
    var body: some Scene {
        // 主窗口
        WindowGroup(id: "main") {
            let feedViewModel = FeedViewModel(appState: appState)
            
            ContentView(feedViewModel: feedViewModel)
                .environmentObject(appState)
                .onAppear {
                    // 主窗口加载时自动打开侧边窗口
                    openWindow(id: "side")
                }
                // 跟踪主窗口的全局位置
                .background(GeometryReader { proxy in
                    Color.clear
                        .onAppear {
                            appState.mainWindowFrame = proxy.frame(in: .global)
                            appState.updateSideWindowPosition()
                        }
                        .onChange(of: proxy.frame(in: .global)) { newFrame in
                            appState.mainWindowFrame = newFrame
                            appState.updateSideWindowPosition()
                        }
                })
        }
        
        // 侧边窗口
        WindowGroup(id: "side") {
            VideoListView()
                .environmentObject(appState)
                .windowStyle(.plain) // 隐藏标题栏和关闭按钮
                .windowResizability(.contentSize) // 锁定窗口大小为内容尺寸
                .onAppear {
                    // 确保侧边窗口启动时位置正确
                    appState.updateSideWindowPosition()
                }
        }
    }
}

关键逻辑说明

  • 自动打开侧边窗口:主窗口的.onAppear中调用openWindow(id: "side"),确保应用启动时同时打开两个窗口;
  • 隐藏侧边窗口控件:.windowStyle(.plain)移除默认标题栏和关闭按钮,.windowResizability(.contentSize)禁止用户调整侧边窗口大小;
  • 位置同步:通过GeometryReader监听主窗口的全局位置变化,每次主窗口拖动时,调用updateSideWindowPosition()将侧边窗口定位到主窗口右侧,保持固定间距和相同高度。

自定义调整

  • 可以修改gap和sideWindowWidth参数来调整窗口间距和侧边窗口宽度;
  • 如果需要侧边窗口高度与主窗口不同,直接修改sideWindow.frame.height的值即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 17:04:57