SwiftUI 2.0 macOS下如何保存窗口尺寸实现重开时大小不变?
SwiftUI 2.0 适配 macOS Big Sur 窗口尺寸持久化方案
问题原因
SwiftUI 2.0 自带的 WindowGroup 场景默认不会持久化窗口的尺寸状态,用户点击左上角关闭按钮后窗口实例被释放,再次打开窗口时只会读取项目预设的默认尺寸,不会保留关闭前用户调整的大小。
实现步骤
- 第一步:使用
@AppStorage定义持久化的窗口尺寸变量,数据会自动存储到系统UserDefaults,即使应用完全退出重启也不会丢失
// 可直接定义在App结构体内部,也可放在全局常量管理文件中 @AppStorage("savedWindowWidth") private var savedWindowWidth: Double = 800 @AppStorage("savedWindowHeight") private var savedWindowHeight: Double = 600
- 第二步:在根视图中添加几何监听,实时更新存储的窗口尺寸,同时给
WindowGroup绑定持久化的默认尺寸
@main struct MyMacApp: App { @AppStorage("savedWindowWidth") private var savedWindowWidth: Double = 800 @AppStorage("savedWindowHeight") private var savedWindowHeight: Double = 600 @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { WindowGroup { ContentView() .frame(minWidth: 600, maxWidth: .infinity, minHeight: 450, maxHeight: .infinity) // 监听窗口尺寸变化,实时保存 .background( GeometryReader { geo in Color.clear .onChange(of: geo.size) { newSize in savedWindowWidth = newSize.width savedWindowHeight = newSize.height } } ) } .windowStyle(.titleBar) // 绑定持久化的尺寸作为窗口默认大小 .defaultSize(width: savedWindowWidth, height: savedWindowHeight) } } // 处理窗口关闭后点击Dock图标重新打开的逻辑 class AppDelegate: NSObject, NSApplicationDelegate { func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool { if !flag { sender.windows.forEach { $0.makeKeyAndOrderFront(nil) } } return true } }
注意事项
- 若使用自定义
Window而非WindowGroup,逻辑完全一致,仅需给Window添加defaultSize修饰符绑定持久化尺寸即可 - 该方案兼容窗口最大化、最小化场景,会自动保留用户调整的非最大化状态窗口尺寸
- 无需额外监听关闭按钮点击事件,尺寸会实时更新存储,关闭前最后一次调整结果会自动留存
内容的提问来源于stack exchange,提问作者LeonardoXUI
相关产品推荐
相关产品推荐

