iOS( swift ): Changing UILabel text with a for loop

标签 ios swift uilabel stride

我有一个 for 循环如下:

@objc private func resetValue() {
    for i in stride(from: value, to: origValue, by: (value > origValue) ? -1 : 1) {
        value = i
    }
    value = origValue
}

value 被设置时,它会更新一个 label:

private var value = 1 {
    didSet {
        updateLabelText()
    }
}

private func updateLabelText() {

    guard let text = label.text else { return }

    if let oldValue = Int(text) { // is of type int?
        let options: UIViewAnimationOptions = (value > oldValue) ? .transitionFlipFromTop : .transitionFlipFromBottom
        UIView.transition(with: label, duration: 0.5, options: options, animations: { self.label.text = "\(value)" }, completion: nil)
    } else {
        label.text = "\(value)"
    }
}

我希望如果 value=5origValue=2,那么标签会翻转数字 5,4,3,2。然而,这并没有发生——请问有什么建议吗?

我试过使用延迟函数:

func delay(_ delay:Double, closure: @escaping ()->()) {
    DispatchQueue.main.asyncAfter(
        deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
}

然后将以下内容放入 stride 代码中:

delay(2.0) { self.value = i }

但是,这似乎也不起作用。

感谢您提供的任何帮助。

最佳答案

UIKit 将无法更新标签,直到您的代码在主线程中完成,在循环完成之后。即使 UIKit 可以在每次循环迭代后更新标签,循环也会在几分之一秒内完成。

结果是您只能看到最终值。

当您尝试引入延迟时,您在 0.5 秒后将更新异步发送到标签;因为它是异步的,所以循环在继续下一次迭代之前不会等待 0.5 秒。这意味着所有延迟更新将在 0.5 秒后执行,但会一个接一个地执行,而不是相隔 0.5 秒。同样,结果是您只能看到最终值,因为其他值设置得太简单以至于看不到。

您可以使用 Timer 实现您想要的:

func count(fromValue: Int, toValue: Int) {
    let stride = fromValue > toValue ? -1 : 1
    self.value = fromValue
    let timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats:true) { [weak self] (timer) in
        guard let strongSelf = self else {
            return
        }
        strongSelf.value += stride
        if strongSelf.value == toValue {
            timer.invalidate()
        }
    }
}

我还会更新 didSet 以将 oldValue 发送到您的 updateLabelText 而不必尝试解析当前文本。

private var value = 1 {
    didSet {
        updateLabelText(oldValue: oldValue, value: value)
    }
}

private func updateLabelText(oldValue: Int, value: Int) {
    guard oldValue != value else {
        self.label.text = "\(value)"
        return
    }

    let options: UIViewAnimationOptions = (value > oldValue) ? .transitionFlipFromTop : .transitionFlipFromBottom
    UIView.transition(with: label, duration: 0.5, options: options, animations: { self.label.text = "\(value)" }, completion: nil)
}

关于iOS( swift ): Changing UILabel text with a for loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51535004/

相关文章:

ios - iOS中如何判断 "TapEnded"

ios - iOS中如何检测音量变化?

ios - 如何在 UILabel 中显示 UITextField 的文本?

objective-c - 在一行UITable中设置多个UILabel

iphone - 当文本太大时,文本不会显示在 UILabel 上。

ios - 我如何将视频从 swift 存储到 firebase 存储中?

iphone - 什么是 UIGobblerGestureRecognizer?

ios - 基于Web服务实现快速更新行标签

Swift Access Control 何时使用类图的前置符号

ios - 'JSONEncoder'/'JSONDecoder' 在此上下文中对于类型查找不明确