如何反复更新 UILabel 并控制其变化速度?

How do I update a UILabel repeatedly and control the speed at which it changes?

我正在创建一个计算结果的应用程序,当显示结果时,我希望它能非常快速地从 0 计数到结果,但速度足够慢,您可以看到数字呼啸而过它很重要。

中的答案似乎与我正在寻找的非常接近,但涉及管理状态,我不知道该怎么做。

我从这个开始:

class ViewController: UIViewController {

let calculator = CalculatorBrain(weightLifted: 0, repetitions: 0)

@IBOutlet weak var weightLifted: UITextField!
@IBOutlet weak var repetitions: UITextField!
@IBOutlet weak var oneRepMax: UILabel!

@IBAction func calculate(sender: UIButton) {
    let lift = Double(weightLifted.text!)
    let reps = Double(repetitions.text!)
    calculator.weightLifted = lift!
    calculator.repetitions = reps!
    let max = Int(calculator.calculateOneRepMax())
    for i in 0...max {
        oneRepMax.text = "\(i)" <-- I think this approach is where I'm going wrong
    }   
}

这是另一个 class:

class CalculatorBrain: NSObject {

var weightLifted: Double
var repetitions: Double
var oneRepMax: Double?

init(weightLifted: Double, repetitions: Double) {
    self.weightLifted = weightLifted
    self.repetitions = repetitions
 }

func calculateOneRepMax() -> Double {
    // Epley Method

    oneRepMax = self.weightLifted * (1 + (self.repetitions)/30)
    return oneRepMax!
 }
}

按照其他线程中的建议,我应该摆脱 for 循环并创建一个将其状态保存在成员变量中的新方法。然后,从事件处理程序调用该方法,设置第一个显示的状态,显示第一个项目,做一些事情,然后 return.

但是因为我想看到 oneRepMax.text 值从 0 开始计数到最大值,所以我不知道如何在没有循环的情况下执行此操作。如果我要创建一个单独的函数来更新 oneRepMax.text 像这样:

func updateCounter(max: Int) -> Int {
     for i in 1...max {
        return max <-- this will just return the max value after the loop stops running which is the same problem I already have
       }
    }

非常感谢对这个新手的任何帮助。

尝试使用计时器。在您的回调中设置您的标签。你需要玩一下间隔来得到你想要的。

timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "yourCallback:", userInfo: nil, repeats: false)

如果您执行这样的循环,文本更新的速度可能与该过程递增数字的速度一样快(极快)。如果我正确理解你的问题,那么你可能想要使用一个大致类似于下面的计时器

let timeInterval = 0.4 // how quickly you want the number to change

var timer = NSTimer.scheduledTimerWithTimeInterval(timeInterval, target: self, selector: #selector(MyClass.updateLabel), userInfo: nil, repeats: true)

var counter: Int = 0
var max: Int = 0

func updateLabel(){
  if(counter == max){
    timer.invalidate()
  }
  // Increment counter and update label
}