SwiftUI macOS应用如何默认隐藏所有窗口?
问题描述
开发纯SwiftUI菜单栏应用时遇到以下问题:
- SwiftUI中定义
Window或WindowGroup时,应用启动总会默认打开至少一个窗口 - 不支持直接对
Window使用条件渲染(如if x { Window() }) - 需求:根据用户默认设置(
showIntroduction)决定是否显示引导窗口,另一个窗口通过菜单栏手动触发打开
当前代码如下:
import SwiftUI @main struct ExampleApp: App { @Environment(\.openWindow) var openWindow @AppStorage("showIntroduction") private var showIntroduction = true init() { if showIntroduction { print("Show introduction") openWindow(id: "introduction") } } var body: some Scene { // How to hide this window by default? Window("Intro", id: "introduction") { WelcomeView() } .windowStyle(.hiddenTitleBar) Settings { SettingsView() } MenuBarExtra { MenuBarView() } label: { Text("Test") } } }
尝试过用.hidden()修饰视图,但该修饰符不支持Window/WindowGroup;若隐藏视图被Window包裹,会出现空窗口。
请问能否通过纯SwiftUI实现需求,还是必须用编程方式创建NSWindow来实现默认不打开窗口?
解决方案
可以通过纯SwiftUI实现,无需依赖NSWindow,核心是利用macOS 13+(Ventura)引入的.defaultPresentationStyle(.hidden)修饰符,让Window默认不显示,仅通过openWindow环境变量按需唤起。
调整后的代码
import SwiftUI @main struct ExampleApp: App { @Environment(\.openWindow) var openWindow @AppStorage("showIntroduction") private var showIntroduction = true init() { // 仅当用户设置为true时,主动唤起引导窗口 if showIntroduction { print("Show introduction") openWindow(id: "introduction") } } var body: some Scene { // 设置引导窗口默认隐藏,仅通过openWindow触发显示 Window("Intro", id: "introduction") { WelcomeView() .onDisappear { // 引导窗口关闭后,标记为已展示 showIntroduction = false } } .windowStyle(.hiddenTitleBar) .defaultPresentationStyle(.hidden) // 关键:默认不渲染窗口 // 若需要手动打开的其他窗口,同样设置默认隐藏 Window("Main Window", id: "main") { MainContentView() } .defaultPresentationStyle(.hidden) Settings { SettingsView() } MenuBarExtra { MenuBarView() } label: { Text("Test") } } }
菜单栏触发打开窗口的实现(MenuBarView示例)
struct MenuBarView: View { @Environment(\.openWindow) var openWindow @Environment(\.dismissWindow) var dismissWindow var body: some View { Button("打开主窗口") { openWindow(id: "main") } Button("关闭主窗口") { dismissWindow(id: "main") } Divider() Button("退出") { NSApplication.shared.terminate(nil) } } }
说明
.defaultPresentationStyle(.hidden)会让Window在应用启动时默认不显示,只有通过openWindow(id:)主动调用才会弹出窗口- 该方案要求系统版本为macOS 13.0+(Ventura)及以上,若需兼容更低版本,则需要通过AppKit的
NSWindow手动创建管理窗口 - 引导窗口关闭时,通过
onDisappear将showIntroduction设为false,避免下次启动重复显示
内容的提问来源于stack exchange,提问作者Dion
相关产品推荐
相关产品推荐

