2. 时间计时器
在你的代码中,leftSecond 的值确实在每次定时器触发时都会更新,但页面没有刷新的原因可能是以下之一:
**1. Date().addingTimeInterval(leftSecond) 的问题**
每次调用 Date().addingTimeInterval(leftSecond) 时,Date() 会返回当前时间,而不是一个固定的基准时间。因此,即使 leftSecond 在减少,Date() 也在不断变化,导致计算结果看起来没有变化。
解决方法:
使用一个固定的基准时间(例如当前时间)来计算剩余时间。
在视图初始化时保存一个基准时间,然后基于这个基准时间计算剩余时间。
修改后的代码:
struct WARoomContentWealthContentView: View {
@State private var day: Int = 2
@State private var leftSecond: TimeInterval = 9999
@State private var startDate: Date = Date() // 保存基准时间
let leftTimer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
VStack {
Spacer().frame(height: 12) // 预留高度
VStack(spacing: 0) {
Image("icon_room_wealth_dealine")
.resizable()
.frame(width: 60, height: 17)
Spacer().frame(height: 6)
Text("\(day)Day \(startDate.addingTimeInterval(leftSecond).toHourToSecondString())")
.systemBoldFont(size: 14)
.multilineTextAlignment(.center)
.foregroundColor(Color(red: 0.95, green: 0.72, blue: 0))
.background(Image("icon_room_wealth_timer_bg"))
.frame(width: 207, height: 24)
}
}
.onReceive(leftTimer) { _ in
if leftSecond > 0 {
leftSecond -= 1
print("lt - left second: \(leftSecond)")
}
}
}
}
关键点:
使用 @State private var startDate: Date = Date() 保存一个固定的基准时间。
在 Text 中,使用 startDate.addingTimeInterval(leftSecond) 计算剩余时间。
**2. toHourToSecondString() 的实现问题**
如果 toHourToSecondString() 是一个自定义方法,确保它的实现是正确的。它应该将 Date 转换为 HH:mm:ss 格式的字符串。示例实现:extension Date { func toHourToSecondString() -> String { let formatter = DateFormatter() formatter.dateFormat = "HH:mm:ss" return formatter.string(from: self) } }
3. SwiftUI 视图更新的条件
SwiftUI 的视图更新依赖于 @State、@Binding、@ObservedObject 等状态变量的变化。如果 leftSecond 的值确实在变化,但视图没有更新,可能是以下原因:
**视图层级问题**:某些父视图可能阻止了子视图的更新。
**视图优化问题**:SwiftUI 可能会优化视图更新,如果它认为视图内容没有变化。
解决方法:
确保 leftSecond 的变化会触发视图更新。可以通过在 Text 中直接打印 leftSecond 来调试:
Text("\(day)Day \(leftSecond)")如果 leftSecond 的值在视图中正确显示并更新,说明问题出在 Date().addingTimeInterval(leftSecond) 或 toHourToSecondString() 的实现上。
4. 调试建议
在 onReceive 中打印 leftSecond 的值,确保它确实在变化。
在 Text 中直接显示 leftSecond,检查视图是否更新。
检查 toHourToSecondString() 的实现,确保它正确地将 Date 转换为字符串。
5. 完整代码
以下是修正后的完整代码:
import SwiftUI
struct WARoomContentWealthContentView: View {
@State private var day: Int = 2
@State private var leftSecond: TimeInterval = 9999
@State private var startDate: Date = Date() // 保存基准时间
let leftTimer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
VStack {
Spacer().frame(height: 12) // 预留高度
VStack(spacing: 0) {
Image("icon_room_wealth_dealine")
.resizable()
.frame(width: 60, height: 17)
Spacer().frame(height: 6)
Text("\(day)Day \(startDate.addingTimeInterval(leftSecond).toHourToSecondString())")
.systemBoldFont(size: 14)
.multilineTextAlignment(.center)
.foregroundColor(Color(red: 0.95, green: 0.72, blue: 0))
.background(Image("icon_room_wealth_timer_bg"))
.frame(width: 207, height: 24)
}
}
.onReceive(leftTimer) { _ in
if leftSecond > 0 {
leftSecond -= 1
print("lt - left second: \(leftSecond)")
}
}
}
}
extension Date {
func toHourToSecondString() -> String {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm:ss"
return formatter.string(from: self)
}
}
struct WARoomContentWealthContentView_Previews: PreviewProvider {
static var previews: some View {
WARoomContentWealthContentView()
}
}
总结
使用固定的基准时间(startDate)来计算剩余时间。
确保 toHourToSecondString() 正确实现。
如果问题仍然存在,可以通过调试 leftSecond 的值和视图更新逻辑来定位问题。
Last updated