问题
在更改.isReversed
属性后,在ios10和ios11上运行相同的代码。
iOS10上的一切都可以。动画问题发生在ios11
条件
对于任何动画,不仅对于特定动画都是如此,并且可以通过观看动画和代码中的方式来证明它。它既发生在模拟器和真实设备上。
详细信息
一旦使用动画创建了一个UiviewPropertyanimator,在运行过程中,我只会调用.pauseAnimation()
并将.isReversed
属性更改为 true 。之后,我恢复动画呼叫:
continueAnimation(withTimingParameters parameters: UITimingCurveProvider?, durationFactor: CGFloat)
在iOS10上的这一点上,动画会顺利改变他的经文,在ios11上,它立即停止并以框架滞后逆转。
如果在代码中,请检查.fractionComplete
的值(在我的UiviewPropertyanimator对象上调用,它使我可以将动画以他的百分比值完成,从0.0开始,以1.0结束).continueAnimation(...
之后
- 在iOS 10上,它仍然存在了片刻,例如动画继续进行,并且只有在时间的分数跳到他的互补段之后。
- 在iOS 11上,它突然跳上了他的互补
在文档上,有与此相关的非更新,仅用于UiviewPropertyanimator的几个新属性,但没有使用,因为我是针对ios10
可能是一个错误,也可能是我缺少一些东西!?
Little Update :刚刚测试,iOS 11.0.1和iOS 11.1 BETA1
上相同的行为在评论中链接时,这仅发生在非线性曲线!
我也已经战斗了一段时间,但是后来我注意到iOS 11中添加到 UIViewPropertyAnimator
的 scrubsLinearly
属性:
默认为true。为动画师提供线性或使用动画仪的当前时间来暂停和磨砂的能力。
请注意,此属性的默认值为true
,这似乎与使用非线性动画曲线发生冲突。这也可能解释了为什么使用线性正时功能时不存在问题。
将scrubsLinearly
设置为false
,动画师似乎正常工作:
let animator = UIViewPropertyAnimator(duration: 0.25, curve: .easeOut) {
...
}
animator.scrubsLinearly = false
在iOS 11上,
fractionComplete
将在您通过animator.isReversed = true
反向动画后反转(即1 - originalFractionComplete
)。持续时间少于0.1s的春季动画将立即完成。
因此,您最初可能希望反向动画运行整个动画持续时间的90%,但是在iOS 11上,反转动画实际上运行10%,因为isReversed
更改了,而10%的持续时间小于0.1s,所以动画将立即完成,看起来好像没有动画发生。
如何修复?
对于iOS 10向后兼容性,在反向动画之前复制fractionComplete
值并将其用于continueAnimation
。
,例如
let fraction = animator.fractionComplete
animator.isReversed = true
animator.continueAnimation(...*fraction*...)
我尝试了许多解决方案,但是没有人对我不起作用。我写了我的解决方案,现在一切都很好。我的解决方案:
拍摄屏幕的图像并显示
完成动画
启动旧状态的新动画
暂停动画并设置进度(1-原始进度)
删除屏幕图像并继续动画
switch pan.state { ... case .ended, .cancelled, .failed: let velocity = pan.velocity(in: view) let reversed: Bool if abs(velocity.y) < 200 { reversed = progress < 0.5 } else { switch state { case .shown: reversed = velocity.y < 0 case .minimized: reversed = velocity.y > 0 } } if reversed { let overlayView = UIScreen.main.snapshotView(afterScreenUpdates: false) view.addSubview(overlayView) animator?.stopAnimation(false) animator?.finishAnimation(at: .end) startAnimation(state: state.opposite) animator?.pauseAnimation() animator?.fractionComplete = 1 - progress overlayView.removeFromSuperview() animator?.continueAnimation(withTimingParameters: nil, durationFactor: 0.5) } else { animator?.continueAnimation(withTimingParameters: nil, durationFactor: 0) }
和动画曲线选项必须为linear
。
animator = UIViewPropertyAnimator(duration: 0.3, curve: .linear) {
startAnimation()
}