You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI技术咨询:如何实现点击按钮后数值按步长1定时递增至目标增量

SwiftUI实现数值逐次递增动画

你的代码存在逻辑问题:jackpot()里的while循环是同步执行的,会瞬间生成10000个延迟0.01秒的异步任务,这些任务几乎同时触发,导致creditScore直接跳变,看不到逐个递增的动画效果;而且循环结束后立刻重置count,会打乱计数逻辑。

以下是两种可行的解决方案:

方案一:递归异步调用

通过递归方式,每次完成一次递增后再触发下一次延迟递增,确保每次递增间隔0.01秒:

import SwiftUI

struct TestView: View {
    @State var creditScore: Int = 5000
    @State var currentIncrement: Int = 0
    let targetIncrement: Int = 10000
    let interval: TimeInterval = 0.01
    
    var body: some View {
        VStack {
            Text("\(creditScore)")
                .font(.largeTitle)
            Button("deal") {
                startIncrement()
            }
            .buttonStyle(.borderedProminent)
        }
    }
    
    func startIncrement() {
        currentIncrement = 0
        incrementStep()
    }
    
    func incrementStep() {
        guard currentIncrement < targetIncrement else { return }
        
        currentIncrement += 1
        creditScore += 1
        
        DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
            incrementStep()
        }
    }
}

方案二:使用Timer

通过Timer定时触发递增,达到目标后停止Timer:

import SwiftUI

struct TestView: View {
    @State var creditScore: Int = 5000
    @State var currentIncrement: Int = 0
    let targetIncrement: Int = 10000
    let interval: TimeInterval = 0.01
    @State private var timer: Timer?
    
    var body: some View {
        VStack {
            Text("\(creditScore)")
                .font(.largeTitle)
            Button("deal") {
                startIncrement()
            }
            .buttonStyle(.borderedProminent)
        }
        .onDisappear(perform: stopTimer)
    }
    
    func startIncrement() {
        timer?.invalidate()
        currentIncrement = 0
        
        timer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { [weak self] timer in
            guard let self = self else {
                timer.invalidate()
                return
            }
            
            if self.currentIncrement < self.targetIncrement {
                self.currentIncrement += 1
                self.creditScore += 1
            } else {
                timer.invalidate()
                self.timer = nil
            }
        }
    }
    
    func stopTimer() {
        timer?.invalidate()
        timer = nil
    }
}

额外说明

  • 遵循Swift命名规范:视图结构体用大驼峰命名(如TestView),变量名用小驼峰;
  • 无需修改的常量用let声明,减少可变状态;
  • 字符串插值"\(creditScore)"比String(creditScore)更简洁;
  • 方案二中使用[weak self]避免循环引用,onDisappear中停止Timer防止内存泄漏。

内容的提问来源于stack exchange,提问作者George T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 02:52:41