通过将 .speed 设置为 -1

问题描述

编辑:我稍微重构了问题并解决了部分问题,现在问题归结为为什么在恢复动画时表示层会出现故障/闪烁。在这一点上,我接受任何可以使动画随意向前和向后恢复而没有问题的答案。我不确定我使用的方法是否正确,我对 Swift 还是很陌生。

注意:底部的示例项目,用于更好地理解问题。

在我的项目中,我通过将图层 CABasicAnimation 属性设置为 .speed 来暂停 0,然后我通过设置图层的 {{1}每当用户滚动滑块时,} 属性就等于 .timeOffset UISlider 属性。按代码:

.value

然后当用户滑动时:

layer.speed = 0 

现在我想在滑块上的用户手势结束时随意向后或向前恢复动画,因此从与当前动画值相关的起点开始。我发现运行平稳的唯一可行解决方案如下,但它只能向前工作:

layer.timeOffset = CFTimeInterval(sender.value)

然后我可以在动画完成时再次暂停它:

let pausedTime = layer.timeOffset
layer.speed = 1.0
layer.timeOffset = 0.0
layer.beginTime = 0.0
let timeSincePause = layer.convertTime(CACurrentMediaTime(),from: nil) - pausedTime
layer.beginTime = timeSincePause

根据我的理解, DispatchQueue.main.asyncAfter(deadline: .now()+1) { layer.timeOffset = 0 layer.speed = 0 } 不仅定义了动画的实际速度,结合 .speed 属性,还定义了动画的方向:如果我将图层的速度设置为等于 {{1 }} 然后动画向后完成。参考关于 .duration 如何工作的 this 答案,我试图更改上面代码片段的参数以恢复动画向后倒退,但没有运气。我认为这会奏效:

-1

但是图层从来没有像这样动画过。该问题似乎与 CAMediaTiming 方法有关。

然后我发现 this 问题与我的基本相同,唯一的答案有一个不错的解决方案。重构一下代码,我只能说:

let pausedTime = layer.timeOffset
layer.timeOffset = 0.0
layer.beginTime = 0.0
let timeSincePause = layer.convertTime(CACurrentMediaTime(),from: nil) - pausedTime
layer.beginTime = timeSincePause
layer.timeOffset = pausedTime*2
layer.speed = -1.0

然而,当动画向后播放时会出现问题,特别是表示层在恢复和完成时都会闪烁。我尝试了各种解决方案但没有运气,我做出了一些推测:

  • 这可能是与 convertTime 相关的问题,因为我可以将其设置为 layer.beginTime = CACurrentMediaTime() layer.speed = -1 DispatchQueue.main.asyncAfter(deadline: .now()+1) { layer.timeOffset = 0 layer.speed = 0 } CAMediaTimingFillMode,但是当它恢复时,动画既不是最终状态也不是初始状态,因此不渲染初始帧;
  • 这是因为我没有保持模态树和表示树同步。

然而,当它在恢复和完成时闪烁/闪烁时,这两个都没有解释。此外,在我看来,动画在向前恢复时的持续时间可能为 1,但在向后恢复时只有 1-timeOffset,不确定。

真的不确定实际问题是什么以及如何解决这个烂摊子。我们非常欢迎所有建议。

对于任何感兴趣的人,这里有一个类似于我的示例项目,其灵感来自另一个问题(动画向前运行,向后运行并捕获故障只需调用 .back)。我知道应该重构代码,但仍然可以达到目的。只需复制、粘贴和运行:

.forwards

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)