Swift - 完成动画之前的完成

时间:2017-12-04 12:48:46

标签: ios swift

我目前遇到的问题是动画功能的完成在动画本身之前结束。

数组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()
            }
        }
    }

1 个答案:

答案 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,但这种方式比使用默认事务更安全。