使用CALayer.speed完成运行动画

问题描述 投票:0回答:1

假设我有一个长时间运行的任务,其进度显示在类似于系统进度条的自定义进度栏中。任务可以比从前缘到后缘的

CALayer.bounds
动画更快完成。在这种情况下,我需要将动画快进到后缘。

目前我用副本替换运行动画,但持续时间要短得多。这种方法工作正常,但需要样板代码。

我想知道是否可以实现相同的结果,但仅使用

CALayer.speed
(例如将其设置为 2 或 3)?幼稚的方法以更高的速度暂停和恢复动画会产生意想不到的结果:进度层就消失了。

ios macos core-animation
1个回答
0
投票

因此,您似乎正在通过对图层边界进行动画处理来运行“进度条”动画。

您的评论指出“3 分钟”,所以您可能有这样的代码:

// create bounds animation for width = 0 to width = bounds.width
let anim = CABasicAnimation(keyPath: "bounds")
anim.fromValue = CGRect(x: 0.0, y: 0.0, width: 0.0, height: bounds.height)
anim.toValue = CGRect(x: 0.0, y: 0.0, width: bounds.width, height: bounds.height)
anim.fillMode = .forwards
anim.isRemovedOnCompletion = false

// 3-minute duration == 180 seconds
anim.duration = 180
    
// start the animation
progressLayer.add(anim, forKey: "progress")

然后,如果“任务”在 2 分 15 秒内完成,您希望“加快”动画的剩余部分。

最简单的方法 - 无需更改图层速度 - 是:

progressLayer.removeAllAnimations()
progressLayer.bounds = CGRect(x: 0.0, y: 0.0, width: bounds.width, height: bounds.height)

这将停止缓慢的动画并立即将图层边界扩展到全宽。请注意,它将使用

CALayer
内置动画,因此图层需要 0.3 秒才能达到全宽。

如果您希望进度条直接“捕捉”到全宽,您可以将其包装在

CATransaction
块中并禁用默认的 0.3 秒动画:

CATransaction.begin()
CATransaction.setDisableActions(true)
progressLayer.removeAllAnimations()
progressLayer.bounds = CGRect(x: 0.0, y: 0.0, width: bounds.width, height: bounds.height)
CATransaction.commit()

如果您确实希望动画继续,但默认的 0.3 秒太快,您可以像这样更改图层速度:

progressLayer.timeOffset = progressLayer.convertTime(CACurrentMediaTime(), from: nil)
progressLayer.beginTime = CACurrentMediaTime()

// changing the layer speed to 2.0 would only *very slightly* increase the speed
//  start with the same value as the duration and observe the result
//  adjust this value until you're happy with the "speeded up" animation completion
progressLayer.speed = 180.0
© www.soinside.com 2019 - 2024. All rights reserved.