如何让AppStorage中的exerciseTime变量每日自动重置?
实现每日自动重置
exerciseTime的可行方案 核心思路
通过额外存储「上次重置的日期」,每次App进入前台或初始化时,对比当前日期与记录的日期,若跨天则重置exerciseTime并更新记录的日期。
具体实现步骤
新增日期存储变量
在@AppStorage中添加变量记录上次重置的日期,用yyyy-MM-dd格式的字符串方便直接对比:@AppStorage("exerciseTime") var exerciseTime = 0.0 @AppStorage("lastResetDate") var lastResetDate = Date().formatted(date: .numeric, time: .omitted)添加场景监听与检查触发
在View的onAppear和前台激活通知中触发日期检查,覆盖App启动和后台切前台的场景:.onAppear { checkDailyReset() } .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in checkDailyReset() }编写检查与重置逻辑
实现核心函数,对比日期后执行重置操作:func checkDailyReset() { let today = Date().formatted(date: .numeric, time: .omitted) if today != lastResetDate { exerciseTime = 0.0 lastResetDate = today } }
整合到你的现有代码
把逻辑嵌入到你的运动计时View中:
struct ExerciseTimerView: View { @AppStorage("exerciseTime") var exerciseTime = 0.0 @AppStorage("lastResetDate") var lastResetDate = Date().formatted(date: .numeric, time: .omitted) // 你的timer、timerStruct等变量定义 let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() @State var timerStruct = TimerStruct() // 假设你有对应的结构体 var body: some View { Text("Time: \(format(seconds: timerStruct.countdownTimer))") .padding() .onReceive(timer) { _ in if timerStruct.countdownTimer > 0 && timerStruct.timerRunning == true { timerStruct.countdownTimer -= 1 exerciseTime += 1.0 } else { timerStruct.timerRunning = false if timerStruct.countdownTimer <= 0, timerStruct.timerRunning == false { timerStruct.isAlertpresented = true reset() } } } .onAppear { checkDailyReset() } .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in checkDailyReset() } } func checkDailyReset() { let today = Date().formatted(date: .numeric, time: .omitted) if today != lastResetDate { exerciseTime = 0.0 lastResetDate = today } } // 你的format、reset等原有函数 func format(seconds: Int) -> String { // 你的格式化逻辑 return String(seconds) } func reset() { // 你的重置逻辑 } } // 假设你的TimerStruct定义 struct TimerStruct { var countdownTimer = 0 var timerRunning = false var isAlertpresented = false }
补充说明
- 若需适配时区差异,可以改用
Calendar.current.startOfDay(for: Date())获取当天起始时间,再转成字符串对比,避免跨时区导致的日期判断错误。 - 监听前台激活通知是为了处理用户跨天后台挂着App的场景,确保回到前台时自动重置数据。
内容的提问来源于stack exchange,提问作者Zudoturiku
相关产品推荐
相关产品推荐

