Swift测验应用:如何正确显示游戏最新游玩日期?
Swift测验应用日期存储与显示问题解决
核心问题分析
- 日期存储时机错误:你在
PlayGameView中用@State private var date: Date = .now初始化日期,这个值是视图创建时的时间,而非游戏结束时的实际时间,导致存入SwiftData的是游戏开始时间,不是结束时间。 - 日期未格式化:直接在
Text中打印Date对象,会显示系统默认的原始日期字符串(如2024-05-20 12:34:56 +0000),无法展示为用户友好的格式。 - 可选:排序逻辑优先级:当前
@Query先按得分倒序再按日期倒序,若需优先展示最新游玩记录,需调整排序顺序。
解决方案
1. 修正日期存储逻辑
删除PlayGameView中多余的date状态变量,在游戏结束时直接获取当前时间存入SwiftData,同时手动保存上下文确保数据持久化:
// 删除PlayGameView中的这一行: // @State private var date: Date = .now // 修改checkGameEnded方法 func checkGameEnded() { if usedMoves.count == maxNumQuestion || numberOfLeftWords == 0 { isGameEnded = true // 游戏结束时获取当前时间 let playerItem = PlayerItem(playerScore: playerScore, date: .now) context.insert(playerItem) // 手动保存上下文,确保数据立即写入 do { try context.save() } catch { print("保存游戏记录失败:\(error.localizedDescription)") } } }
2. 格式化日期显示
在ContentView中添加DateFormatter,将原始Date对象转换为用户友好的中文格式:
struct ContentView: View { @Environment(\.modelContext) var context // 若需优先展示最新游玩记录,调整排序顺序为日期优先 @Query(sort: [SortDescriptor(\PlayerItem.date, order: .reverse),SortDescriptor(\PlayerItem.playerScore, order: .reverse)]) var playerItems: [PlayerItem] // 初始化日期格式化器 private let dateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .medium // 日期格式:2024/5/20 formatter.timeStyle = .short // 时间格式:14:30 formatter.locale = Locale(identifier: "zh_CN") // 设置中文区域 return formatter }() var body: some View { Text("Your best score : \(playerItems.first?.playerScore ?? 0)") .foregroundStyle(.white) .bold() .font(.title2) .offset(x:-10) .padding(.bottom,40) if let firstItem = playerItems.first { // 使用格式化后的日期字符串 Text("最新游玩:\(dateFormatter.string(from: firstItem.date))") .foregroundStyle(.white) .bold() .font(.title2) .padding(.bottom,40) } else { Text("Let's study!") .foregroundStyle(.white) .bold() .font(.title2) .padding(.bottom,40) } } }
3. 确保SwiftData容器配置正确
检查App入口是否正确配置了ModelContainer,否则数据无法持久化:
@main struct QuizApp: App { let container: ModelContainer init() { do { container = try ModelContainer(for: PlayerItem.self) } catch { fatalError("初始化SwiftData容器失败:\(error)") } } var body: some Scene { WindowGroup { ContentView() .modelContainer(container) } } }
验证步骤
- 运行应用,完成一局游戏,结束时触发
checkGameEnded方法。 - 返回
ContentView,查看最新游玩日期是否显示为格式化后的正确时间。 - 重启应用,确认日期记录依然存在(验证持久化生效)。
内容的提问来源于stack exchange,提问作者Iku
相关产品推荐
相关产品推荐

