Swift实现每日仅可输入一次运动时间的逻辑问题求助
问题修正:实现日期变更后才能再次输入运动时间
核心问题分析
原代码逻辑存在两个关键错误:
- 直接用
Date()和当天0点的dateWithoutTime做相等判断,因为Date()包含具体时分秒,永远不可能和0点的日期相等,导致逻辑完全失效。 - 仅用bool值存储状态,无法区分“未输入过”和“已输入但日期未变更”两种情况,无法准确判断日期是否更新。
正确思路:存储上次输入的日期,每次操作时对比当前日期与上次输入日期,若不同则允许再次输入。
修正后的ViewModel代码
// 检查是否允许输入运动时间 func checkInputAvailability() { let currentDate = Calendar.current.startOfDay(for: Date()) // 从UserDefaults获取上次输入的日期,默认值为遥远的过去(表示从未输入过) let lastInputDate = UserDefaults.standard.object(forKey: "lastInputDate") as? Date ?? Date.distantPast // 比较当前日期和上次输入日期,不同则允许输入 inputDateAvailable.value = !Calendar.current.isDate(currentDate, inSameDayAs: lastInputDate) } // 保存本次输入的日期(即当前日期的0点) func saveLastInputDate() { let currentDateStart = Calendar.current.startOfDay(for: Date()) UserDefaults.standard.set(currentDateStart, forKey: "lastInputDate") } // 原有的业务逻辑方法保留 func profileBtnDidTap() { // 执行输入运动时间的逻辑 } func pushProfileGraphVC() { // 跳转到图表页面的逻辑 }
修正后的ViewController代码
@objc func profileBtnDidTap(_ sender: UIButton) { viewModel.checkInputAvailability() guard viewModel.inputDateAvailable.value else { viewModel.pushProfileGraphVC() return } // 允许输入,执行输入逻辑后保存当前日期 viewModel.profileBtnDidTap() viewModel.saveLastInputDate() } override func configureVC() { // 初始化时检查输入可用性 viewModel.checkInputAvailability() }
关键改动说明
- 替换bool值存储为日期存储,用
lastInputDate记录上次输入的日期(取当天0点),能准确判断日期是否变更。 - 使用
Calendar.current.startOfDay(for: Date())获取当天的起始时间,避免时区和时分秒的干扰。 - 初始化时调用
checkInputAvailability(),确保页面加载时就正确显示输入状态。 - 点击按钮时先检查可用性,允许输入则执行操作并保存当前日期,不允许则直接跳转图表页面。
内容的提问来源于stack exchange,提问作者Dohyeon
相关产品推荐
相关产品推荐

