Swift: 如何在更改标签之前完成 UIView 绘制动画

Swift: how to finish a UIView draw animation before changing a label

我对动画的时间有一点疑问。

顺序应该是:

  1. 按钮被按下
  2. 显示动画
  3. 标签已更改

实际上顺序是:

  1. 按钮被按下
  2. 标签已更改
  3. 显示动画

这里是主要代码 VC:

import Foundation
import UIKit

class MainVC: UIViewController {

  var counter: Int = 0

  @IBOutlet weak var counterLabel: UILabel!
  
  @IBOutlet weak var nextButton: UIButton!

  @IBOutlet weak var animationView: AnimationView!

  @IBAction func nextButtonPressed(_ sender: UIButton) {
     counter += 1
     animationView.progress = 1
     //this view draws a progress bar and animates it from 0 to 100% via CABasicAnimation. 
     counterLabel.text = "\(counter)"
     animationView.progress = 0 
     //the progress bar is reset
  }

  override func viewDidLoad() {
     super.viewDidLoad()
     nextButton.setTitle("Next")
     counterLabel.text = "\(counter)"
  }

}

我已经尝试过调度队列,但我就是无法让它正常工作。关于如何解决这个问题的任何想法?

您没有展示足够多的代码,我们无法专门为您提供帮助。

一般来说,您会设置一些对象作为您的 CAAnimation 的委托,并实现方法 func animationDidStop(_ anim: CAAnimation, finished flag: Bool)

在该方法中,您将更改标签文本(假设 finished == true。)

我不太喜欢动画的委托模式。如果你有多个动画,处理每个动画的自定义完成代码可能会很痛苦。我所做的是利用这样一个事实,即您可以将对象附加到 CAAnimation 对象,并将闭包附加到动画。然后我将视图控制器设置为委托,在视图控制器的 animationDidStop() 中,我寻找附加到动画的闭包,如果有则执行它。

编辑:

有关使用键值编码将对象附加到 CAAnimationCALayer 对象的讨论,请参阅本文:

Core Animation Key-value coding extensions

很老了,用Objective-C写的,但是Swift的概念是一样的,很有用。有关键值编码的更一般性讨论, 更新为 Swift,请参阅本文:https://developer.apple.com/documentation/objectivec/nsobject/nskeyvaluecoding

(Swift中你需要知道的两个函数是setValue(_:forKeyPath:)value(forKey:)。)