问题描述
编辑:我稍微重构了问题并解决了部分问题,现在问题归结为为什么在恢复动画时表示层会出现故障/闪烁。在这一点上,我接受任何可以使动画随意向前和向后恢复而没有问题的答案。我不确定我使用的方法是否正确,我对 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 (将#修改为@)