visionOS中如何使两个窗口同时激活并保持可见?
解决多窗口同时保持全亮度(活跃视觉状态)的问题
问题原因
这是系统默认的视觉区分机制——非当前交互的窗口会降低亮度,帮助用户快速识别正在操作的活跃窗口。
解决方案
要让多个窗口同时保持全亮度,可通过以下两种方式实现:
方式1:修改窗口层级(适配macOS/visionOS)
通过NSWindowRepresentable获取窗口实例,将窗口层级设为浮动级别,使其始终保持视觉活跃状态:
struct AlwaysActiveWindowView: NSWindowRepresentable { var content: () -> ContentView2 func makeNSWindow(context: Context) -> NSWindow { let window = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 480, height: 300), styleMask: [.titled, .closable, .resizable, .miniaturizable], backing: .buffered, defer: false ) window.contentView = NSHostingView(rootView: content()) // 设置为浮动窗口层级,始终保持全亮度 window.level = .floating return window } func updateNSWindow(_ window: NSWindow, context: Context) {} }
替换App结构体中对应窗口的内容:
@main struct DragAndDropApp: App { var sharedState = SharedState() var body: some Scene { WindowGroup { ContentView() } WindowGroup(id: "SecondWindow") { AlwaysActiveWindowView { ContentView2() .environmentObject(sharedState) .colorScheme(.dark) } } ImmersiveSpace(id: "ImmersiveSpace") { ImmersiveView() }.immersionStyle(selection: .constant(.full), in: .full) } }
方式2:禁用非活跃窗口变暗(仅macOS)
如果不想修改窗口层级,可直接关闭单个窗口的非活跃变暗效果:
struct DisableInactiveDimView: NSWindowRepresentable { var content: () -> ContentView2 func makeNSWindow(context: Context) -> NSWindow { let window = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 480, height: 300), styleMask: [.titled, .closable, .resizable, .miniaturizable], backing: .buffered, defer: false ) window.contentView = NSHostingView(rootView: content()) // 关闭非活跃窗口变暗效果 window.isOpaque = true window.appearance = NSAppearance(named: .darkAqua) window.invalidateShadow() return window } func updateNSWindow(_ window: NSWindow, context: Context) {} }
同样替换App中对应窗口的内容即可生效。
注意事项
- visionOS环境下,浮动窗口层级是更可靠的实现方案,符合系统交互逻辑。
- 修改窗口层级会影响窗口堆叠顺序,需根据实际场景调整。

内容的提问来源于stack exchange,提问作者János
相关产品推荐
相关产品推荐

