SwiftUI macOS应用:新窗口无法恢复用户上次设置尺寸问题
解决macOS SwiftUI窗口记忆尺寸问题
你的需求完全可以实现,问题出在用SwiftUI的.frame修饰符控制窗口尺寸的思路不对——.frame是用来约束视图内容的尺寸,而非直接控制窗口本身的初始大小,所以idealWidth/Height会被窗口的默认行为覆盖,优先使用最小尺寸。
正确的做法是直接在WindowGroup层面配置窗口的初始尺寸和最小限制,结合@AppStorage存储的用户自定义尺寸,同时确保初始尺寸不低于最小要求:
修改后的完整代码
import SwiftUI @main struct so_RememberWindowSizeApp: App { @AppStorage("windowSizeHeight") var windowSizeHeight = 800.0 @AppStorage("windowSizeWidth") var windowSizeWidth = 1280.0 // 确保存储的尺寸不小于最小值 private var defaultWindowWidth: Double { max(windowSizeWidth, 1280) } private var defaultWindowHeight: Double { max(windowSizeHeight, 800) } var body: some Scene { WindowGroup { ContentView() .overlay { GeometryReader { proxy in Color.clear .onAppear { print("👀 Startup Width: \(proxy.size.width), Startup Height: \(proxy.size.height)") } .onChange(of: proxy.size) { _, newValue in // 更新存储时同样确保不低于最小值 windowSizeHeight = max(newValue.height, 800) windowSizeWidth = max(newValue.width, 1280) print("👀 New Width: \(windowSizeWidth), New Height: \(windowSizeHeight)") } } } } // 设置窗口可调整性,并指定初始默认尺寸 .windowResizability(.contentSize) .defaultSize(width: defaultWindowWidth, height: defaultWindowHeight) // 限制窗口最小尺寸 .windowMinSize(width: 1280, height: 800) } } struct ContentView: View { @AppStorage("windowSizeHeight") var windowSizeHeight = 800.0 @AppStorage("windowSizeWidth") var windowSizeWidth = 1280.0 var body: some View { VStack(spacing: 32.0) { Text("Current Height in UserDefaults: \(windowSizeHeight)") Text("Current Width in UserDefaults: \(windowSizeWidth)") } .frame(maxWidth: .infinity, maxHeight: .infinity) } } #Preview { ContentView() }
关键改动说明
- 移除
.frame修饰符:不再用视图的frame约束窗口,转而直接配置WindowGroup的窗口属性 - 添加窗口尺寸配置:
.windowMinSize:直接设置窗口的最小尺寸,确保窗口无法被拖到小于1280x800.defaultSize:使用存储的尺寸(同时通过max确保不低于最小值)作为新窗口的初始大小
- 更新存储逻辑:在保存用户调整的尺寸时,同样用
max过滤掉小于最小值的情况,避免存储非法尺寸
这样修改后,Cmd+N打开新窗口时,会直接加载用户上次调整的尺寸(如果该尺寸≥1280x800),否则用最小尺寸,完全符合你的需求。
内容的提问来源于stack exchange,提问作者appfrosch
相关产品推荐
相关产品推荐

