SwiftUI iOS15进度加载动画实现问题:数值滚动至目标值报错排查
SwiftUI 进度数值滚动动画问题修复
原代码核心问题
number是不可变let常量且为String类型,无法直接修改和参与数值运算- 未使用SwiftUI状态属性(如@State),数值变化无法触发视图更新
- 类型转换逻辑错误,String不能直接与Double比较/赋值
- Timer定义方式存在生命周期隐患
修正后的代码实现
1. 调整Params结构体(用数值类型存储目标值)
struct Params: Identifiable { let id = UUID() let num: Int // 替换String为Int,避免类型转换问题 } extension Params { static func getAll() -> [Params] { return [ Params(num: 650), Params(num: 80), Params(num: 900) ] } }
2. 实现带滚动动画的进度视图
struct AnimatedProgressView: View { let targetNumber: Int let total: Int @State private var currentValue: Double = 0 // 用@State管理动态数值,触发视图更新 var body: some View { ProgressView("\(Int(currentValue))/\(total)", value: currentValue, total: Double(total)) .onAppear { // 启动定时器,逐步增加数值到目标值 let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in let increment = Double.random(in: 0...4) if currentValue + increment < Double(targetNumber) { currentValue += increment } else { currentValue = Double(targetNumber) timer.invalidate() // 达到目标后停止定时器 } } timer.fire() // 立即触发一次,消除初始延迟 } } } // 使用示例 struct ContentView: View { let params = Params.getAll() let total = 1000 // 自定义总数 var body: some View { VStack(spacing: 20) { ForEach(params) { param in AnimatedProgressView(targetNumber: param.num, total: total) } } .padding() } }
关键修复点说明
- 用
@State属性currentValue管理当前进度,确保数值变化时自动刷新视图 - 定时器在视图出现时启动,达到目标值后立即停止,避免资源浪费
- 全程使用数值类型运算,消除字符串转数值的错误风险
- 增加
timer.fire()避免初始状态的延迟显示
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

