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

Swift测验应用:如何正确显示游戏最新游玩日期?

Swift测验应用日期存储与显示问题解决

核心问题分析

  1. 日期存储时机错误:你在PlayGameView中用@State private var date: Date = .now初始化日期,这个值是视图创建时的时间,而非游戏结束时的实际时间,导致存入SwiftData的是游戏开始时间,不是结束时间。
  2. 日期未格式化:直接在Text中打印Date对象,会显示系统默认的原始日期字符串(如2024-05-20 12:34:56 +0000),无法展示为用户友好的格式。
  3. 可选:排序逻辑优先级:当前@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)
        }
    }
}

验证步骤

  1. 运行应用,完成一局游戏,结束时触发checkGameEnded方法。
  2. 返回ContentView,查看最新游玩日期是否显示为格式化后的正确时间。
  3. 重启应用,确认日期记录依然存在(验证持久化生效)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:25:00