我目前遇到的问题是动画功能的完成在动画本身之前结束。
数组progressBar[]
包含多个UIProgressViews
。当一个人完成动画制作时,我希望下一个动画开始制作动画,依此类推。但是现在他们都马上就开始了
我怎样才能解决这个问题?
@objc func updateProgress() {
if self.index < self.images.count {
progressBar[index].setProgress(0.01, animated: false)
group.enter()
DispatchQueue.main.async {
UIView.animate(withDuration: 5, delay: 0.0, options: .curveLinear, animations: {
self.progressBar[self.index].setProgress(1.0, animated: true)
}, completion: { (finished: Bool) in
if finished == true {
self.group.leave()
}
})
}
group.notify(queue: .main) {
self.index += 1
self.updateProgress()
}
}
}
答案 0 :(得分:3)
问题是UIView.animate()
只能用于可动画的属性,而progress
不是动画属性。 “动画”在这里意味着“Core Animation可以在外部制作动画”。 UIProgressView
执行自己的内部动画,并与外部动画冲突。这UIProgressView
有点过于聪明,但我们可以解决它。
UIProgressView
确实使用了Core Animation,因此会触发CATransaction
完成块。但是,它并不尊重当前CATransaction
的持续时间,因为它确实支持当前UIView动画的持续时间,所以我感到困惑。我实际上并不确定这两个都是真的(我认为UIView动画持续时间将在事务上实现),但似乎是这样。
考虑到这一点,你正在尝试做的事情的方式如下:
func updateProgress() {
if self.index < self.images.count {
progressBar[index].setProgress(0.01, animated: false)
CATransaction.begin()
CATransaction.setCompletionBlock {
self.index += 1
self.updateProgress()
}
UIView.animate(withDuration: 5, delay: 0, options: .curveLinear,
animations: {
self.progressBar[self.index].setProgress(1.0, animated: true)
})
CATransaction.commit()
}
}
我正在这里创建一个嵌套事务(使用begin / commit),以防万一在此事务期间创建了其他完成块。这是不太可能的,并且代码“工作”而不调用begin / commit,但这种方式比使用默认事务更安全。