UIProgressView 动画只能正常工作一次

UIProgressView animation works correctly only once

我正在执行一些 HTTP 请求,在收到 HTTP 响应时设置 class 属性 并使用 willSet 更新进度条值。进度条动画只作用一次

var data: CompatibilityData? {
    didSet {
        self.progressView.setProgress(0.0, animated: false)

        UIView.animate(withDuration: 2.0) {
            self.progressView.setProgress(data.percentage! / 100, animated: true)
        }
    }
}

...

let task = URLSession.shared.dataTask(with: url) { data, response, error in
    ...

    if let data = data {
        ...

        DispatchQueue.main.async {
            if let r = response {
                self.data = r
            }
        }
     }
}

task.resume()

当我第二次收到 HTTP 响应时,预期的行为会将进度重置为 0,并再次将其从 0 动画化为 data.percentage。目前它从旧的 data.percentage 移动到新的 data.percentage.

答案如下:如果您希望 progressView 为 0.0,只需让它设置动画即可。

var data: CompatibilityData? {
didSet {
    self.progressView.setProgress(0.0, animated:**true**)

    UIView.animate(withDuration: 2.0) {
        self.progressView.setProgress(data.percentage! / 100, animated: true)
    }
}
}

有助于理解动画在抽象层的工作原理。仅仅因为进度值已更改并不意味着表示其值的条形的笔画路径已更新以反映其更改为 0。

这意味着当视图想要动画时,它将从它的 "old stroke path" 值(仍然是之前的值)变为 "new stroke path" 值,更新后的值。

为了每次从 0 开始显示动画的百分比变化,您必须更新视图的布局,而不仅仅是基础值。

通话中

self.progressView.layoutIfNeeded()

设置基础进度值后,将更新 progressView Bar 以在下一个绘图周期反映正确的值,并且会在动画开始之前发生,以便动画从 0 变为新值。

除非您想采用@E.Coms 方法并等待视图完成动画后回到 0,然后再对新值进行动画处理。虽然这看起来很酷,但它可能不是您想要的效果。