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

SwiftUI for macOS:如何关闭WindowGroup所有窗口并阻止重启恢复?

解决SwiftUI macOS数据驱动窗口组的持久化问题

一、直接禁用窗口组的持久化(推荐方案)

从macOS 13(Ventura)开始,WindowGroup支持通过persistence参数关闭持久化特性,从根源解决窗口重启恢复的问题——不管是正常退出还是意外崩溃,重启后该窗口组下的所有详情窗口都不会自动打开。

修改你的App.swift代码,给数据驱动的WindowGroup添加persistence: .none:

@main
struct MyApp: App {
    @State var vm = ViewModel()

    var body: some Scene {
        WindowGroup { // 主窗口
            ContentView()
                .environment(vm)
        }
        // 禁用窗口状态持久化
        WindowGroup(for: Item.ID.self, persistence: .none) { $itemID in
            ItemDetails(itemID: itemID)
                .environment(vm)
        }
    }
}

二、程序化关闭所有窗口(兼容旧系统/主动清理场景)

如果需要兼容macOS 13以下的版本,或者需要主动关闭所有详情窗口,可以借助AppKit的API实现精准清理:

1. 给窗口组设置唯一标识符

先修改App.swift中的详情窗口组,添加专属ID用于后续识别:

WindowGroup(for: Item.ID.self, id: "ItemDetailsWindow") { $itemID in
    ItemDetails(itemID: itemID)
        .environment(vm)
}

2. 实现批量关闭方法

在你的ViewModel中添加遍历并关闭目标窗口的逻辑:

class ViewModel: ObservableObject {
    // 你的现有业务代码...
    
    func closeAllItemDetailsWindows() {
        NSApplication.shared.windows.forEach { window in
            // 通过标识符精准匹配详情窗口
            if window.identifier == NSUserInterfaceItemIdentifier("ItemDetailsWindow") {
                window.close()
            }
        }
    }
}

3. 触发清理操作

  • 启动时自动清理:在主视图的onAppear中调用,处理意外退出后的遗留窗口(注意:此场景下窗口会短暂显示再关闭)
struct ContentView: View {
    @Environment(ViewModel.self) private var vm
    @Environment(\.openWindow) private var openWindow

    var body: some View {
        ForEach(vm.items) { item in
            Button(item.name) {
                openWindow(value: item.id)
            }
        }
        .onAppear {
            vm.closeAllItemDetailsWindows()
        }
    }
}
  • 手动触发:添加按钮让用户主动关闭所有详情窗口
// 在ContentView中添加按钮
Button("关闭所有详情窗口") {
    vm.closeAllItemDetailsWindows()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 15:22:30