TimelineView停止更新:点击Indulge按钮后UI不再刷新问题
问题与修复:Indulge按钮点击后UI停止更新
问题现象
首次点击Indulge按钮后,UI出现异常:
indulgences数组计数不再递增- 计算属性
pctIntervalComplete停止更新,进度条也不再变化
根因分析
问题出在Habit结构体的Hashable实现上:
- 当前仅手动实现了
==方法,仅比较habitId - Swift自动合成的
hash(into:)方法会计算所有属性(包括indulgences数组)的哈希值 - 调用
addIndulgence()修改indulgences后,Habit的哈希值发生变化,ForEach无法识别这是同一个实例,导致UI与状态的绑定断裂,后续更新无法触发刷新
修复方案
手动实现hash(into:)方法,仅基于habitId计算哈希值,保持与==逻辑一致,确保Habit的身份判断完全由唯一的habitId决定:
struct Habit: Hashable { static func == (lhs: Habit, rhs: Habit) -> Bool { return lhs.habitId == rhs.habitId } // 手动实现hash(into:),仅关联habitId func hash(into hasher: inout Hasher) { hasher.combine(habitId) } // 以下原有代码保持不变 public let habitId: UUID public var habitName: String public var indulgences: [Indulgence] public var daysInterval: Int public var hoursInterval: Int public var minsInterval: Int public var secsInterval: Int public var daysIncrease: Int public var hoursIncrease: Int public var minsIncrease: Int public var secsIncrease: Int private let minutesToSeconds: Int = 60 private let hoursToSeconds: Int = 3600 private let daysToSeconds: Int = 86400 public var pctIntervalComplete: Double { guard let latestIndulgence = indulgences.last else { return 0.0 } let currentInterval = Date.now.timeIntervalSinceReferenceDate - latestIndulgence.timestamp.timeIntervalSinceReferenceDate return currentInterval / targetIntervalInSeconds } public var isIntervalComplete: Bool { return pctIntervalComplete >= 1.0 } private var targetIntervalInSeconds: TimeInterval { return TimeInterval((daysInterval * daysToSeconds) + (hoursInterval * hoursToSeconds) + (minsInterval * minutesToSeconds) + secsInterval) } init(habitId: UUID = UUID(), habitName: String) { self.habitId = habitId self.habitName = habitName indulgences = [Indulgence]() daysInterval = 0 hoursInterval = 0 minsInterval = 1 secsInterval = 0 daysIncrease = 0 hoursIncrease = 0 minsIncrease = 1 secsIncrease = 0 } mutating public func addIndulgence() { var i = Indulgence(habitId: self.habitId) indulgences.append(i) } }
修复原理
让hash(into:)仅依赖habitId后,无论Habit的其他属性如何变化,其哈希值始终保持一致,ForEach能持续识别同一个实例,状态更新就能正常触发UI刷新。
内容的提问来源于stack exchange,提问作者Legion
相关产品推荐
相关产品推荐

