SwiftUI Mac多窗口应用状态恢复异常问题求助
SwiftUI Mac应用窗口状态恢复失败问题解决思路
问题描述
按照状态恢复原则,Mac应用重启后应自动恢复之前打开的窗口,但当前实现中,重启后恢复的窗口显示no person for you,无法正确显示之前的人物信息。
现有代码实现
主程序代码
@main struct WindowTestApp: App { var body: some Scene { WindowGroup { ContentView() } WindowGroup("Title", for: Person.ID.self){ $id in TestView(personID: $id) } } }
窗口打开按钮代码
struct OpenWindowButton: View { @Environment(\.openWindow) var openWindow let person: Person var body: some View { Button("Open new window"){ openWindow(value: person.id) } } }
模型代码
struct Person:Identifiable, Hashable{ let name: String let age: Int var id: UUID } let people:[Person] = [ Person(name: "Jack", age: 41, id: UUID()), Person(name: "Mary", age: 32, id: UUID()), Person(name: "Linda", age: 18, id: UUID()), Person(name: "Joe", age: 13, id: UUID()), Person(name: "Kid", age: 1, id: UUID()) ]
ContentView代码
struct ContentView: View { var body: some View { List{ ForEach(people, id:\.self){person in VStack{ Text(person.name) }.contextMenu{ OpenWindowButton(person: person) } } } } }
TestView代码
struct TestView: View { @Binding var personID: Person.ID? var body: some View { if let personFromID = people.first(where: {$0.id == personID}){ VStack { Text(personFromID.name) Text("\(personFromID.age)") } }else{ Text("no person for you") } } }
解决思路
核心问题
重启后窗口无法匹配到对应Person的根本原因是:people数组中的每个Person的id是每次APP启动时重新生成的新UUID,而状态恢复保存的是上次启动时的旧UUID,两者无法匹配,导致people.first(where:)返回nil。
具体修复步骤
固定Person的ID值
将people数组中的UUID改为固定值,避免每次启动生成新ID。示例修改如下:let people:[Person] = [ Person(name: "Jack", age: 41, id: UUID(uuidString: "A0B1C2D3-E4F5-6789-ABCD-EF1234567890")!), Person(name: "Mary", age: 32, id: UUID(uuidString: "12345678-1234-5678-1234-567812345678")!), Person(name: "Linda", age: 18, id: UUID(uuidString: "98765432-1234-5678-1234-567812345678")!), Person(name: "Joe", age: 13, id: UUID(uuidString: "11112222-3333-4444-5555-666677778888")!), Person(name: "Kid", age: 1, id: UUID(uuidString: "99998888-7777-6666-5555-444433332222")!) ]这样每次启动APP,所有Person的ID保持一致,恢复窗口时保存的旧ID就能匹配到对应的Person。
确认状态恢复开关开启
检查项目设置中的状态恢复选项:在项目的Info.plist中添加NSQuitAlwaysKeepsWindows键,设置值为YES,确保APP允许窗口状态恢复。动态数据场景扩展
如果需要使用动态生成的Person数据,需将数据持久化存储(比如用UserDefaults、CoreData或文件存储),确保重启后能加载到和上次相同ID的Person数据,而不是重新生成新数据。
内容的提问来源于stack exchange,提问作者erdo
相关产品推荐
相关产品推荐

