如何禁止macOS自动恢复特定SwiftUI WindowGroup窗口
macOS SwiftUI 特定窗口禁用启动自动恢复方案
原生禁用自动恢复的最简方案
直接给对应WindowGroup添加SwiftUI原生的恢复行为修饰符,不需要在应用终止逻辑里遍历改窗口属性,从根源上阻止系统把该窗口加入启动自动恢复列表:
WindowGroup("StandingsView") { StandingsView() .environmentObject(appServices) } .handlesExternalEvents(matching: Set(arrayLiteral: "StandingsView")) .restorationBehavior(.disabled)
这个修饰符是SwiftUI 3+ 针对macOS窗口场景提供的原生接口,设置.disabled后系统不会为该窗口生成自动恢复项,不会出现你之前在applicationShouldTerminate里修改属性偶发失效的问题——后者的问题在于系统进入终止流程前就已经缓存了待恢复窗口列表,这时候再修改isRestorable属性不会同步更新系统缓存。
保留窗口尺寸状态、仅用户触发时加载的最优实现
如果需要复用系统已经保存的窗口尺寸、位置等状态,不需要自己手动存储状态数据,只需要拦截启动阶段的自动恢复窗口即可:
- 首先移除你之前在
applicationShouldTerminate里修改窗口恢复属性、提前关窗口的逻辑,保留系统默认的窗口状态存储能力 - 在遵循
App协议的应用主结构中,添加应用启动完成的事件监听,启动后立刻关闭系统自动恢复出来的、依赖未初始化完成的目标窗口:
@main struct RaceStratLiteApp: App { // 你原有的appServices等状态定义 var body: some Scene { // 你原有的WindowGroup、Window等场景定义 WindowGroup("StandingsView") { StandingsView() .environmentObject(appServices) } .handlesExternalEvents(matching: Set(arrayLiteral: "StandingsView")) } } // 扩展添加启动监听 extension RaceStratLiteApp { init() { NotificationCenter.default.addObserver(forName: NSApplication.didFinishLaunchingNotification, object: nil, queue: .main) { _ in // 遍历启动时自动恢复的窗口,关闭所有依赖appServices的目标窗口 for window in NSApplication.shared.windows { if window.identifier?.rawValue == "StandingsView" { window.close() } } } } }
- 保留你原有的URL触发打开窗口的逻辑,等appServices初始化完成、用户点击「start」按钮后再通过
NSWorkspace.shared.open(standingsURL)打开对应窗口,此时系统会自动使用之前存储的窗口尺寸、位置状态,不需要额外手动赋值。
备选自定义状态存储方案
如果需要更灵活的状态控制(比如多窗口布局、自定义UI状态的恢复),可以完全接管状态存储逻辑:
- 在窗口关闭、应用终止时,将目标窗口的frame、对应UI状态存储到
UserDefaults或本地配置文件 - 用户触发打开窗口时,新窗口创建完成后从本地读取存储的状态,手动给窗口设置尺寸、恢复UI参数即可
内容的提问来源于stack exchange,提问作者Scott
相关产品推荐
相关产品推荐

