我使用此代码旋转任何视图:
func rotateAnimation(theView: UIView, duration: CFTimeInterval = 20.0, repeatCount: Float = 200, toValue: CGFloat = CGFloat(.pi * 2.0)) {
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.fromValue = 0.0
rotateAnimation.toValue = toValue
rotateAnimation.duration = duration
rotateAnimation.repeatCount = repeatCount
theView.layer.add(rotateAnimation, forKey: nil)
}
我想知道如何加快当前正在运行的动画。例如,如果UIView正在使用上面的代码进行旋转,那么如何通过良好的转换使速度提高两倍呢?
所以:调用rotateAnimation :以正常速度旋转 - > 电话?功能? - > UIView将顺利地更快地旋转到所需的速度 - > UIView将以所需的速度继续旋转。
感谢您的帮助。
答案 0 :(得分:2)
请尝试以下代码
let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (timer) in
self.viewToMove.layer.timeOffset = self.viewToMove.layer.convertTime(CACurrentMediaTime(), from: nil)
self.viewToMove.layer.beginTime = CACurrentMediaTime()
self.viewToMove.layer.speed += 0.5
}
timer.fire()
它会非常顺利地提高动画速度
答案 1 :(得分:0)
尝试第二个动画
您可以设置较小的持续时间以提高速度
func rotateAnimation(theView: UIView, duration: CFTimeInterval = 0.4, repeatCount: Float = 200, toValue: CGFloat = CGFloat(.pi * 2.0)) {
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.fromValue = 0.0
rotateAnimation.toValue = toValue
rotateAnimation.duration = duration
rotateAnimation.repeatCount = repeatCount
并设置shouldRasterize = true以获得更好的性能
theView.layer.rasterizationScale = UIScreen.main.scale
theView.layer.shouldRasterize = true
对两个动画使用相同的键
theView.layer.add(rotateAnimation, forKey: "animation")
}
答案 2 :(得分:0)
将repeatcount设置为1,并在每个动画停止后重新添加动画。我不确定这是否会导致您的方案中的性能问题,因为我使用非常基本的方形视图进行了测试。
通过添加CAMediaTimingFunction
参数,您可以控制是否使用kCAMediaTimingFunctionLinear
- 用于那些正常的动画循环,或者使用自定义的参数,例如kCAMediaTimingFunctionEaseIn
- - 使关键动画帧显示平滑过渡。
// your function to start the acceleration
@IBAction func buttonTapped(_ sender: UIButton) {
accel = true
speed = 2.0
timeOffset = self.rect.layer.convertTime(CACurrentMediaTime(), from: nil)
timeOffset = timeOffset - lastStart
// memorize the timeoffset, new speed (2x) and a boolean flag
self.rect.layer.removeAllAnimations()
}
// delegate - memorize the CFTimeInterval
func animationDidStart(_ anim: CAAnimation) {
lastStart = self.rect.layer.convertTime(CACurrentMediaTime(), from: nil)
}
// delegate - start a new loop of animation each time it's stopped
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
if accel {
accel = false
let opt = CAMediaTimingFunction(controlPoints: 0.5, 0.2, 0.9, 0.7)
rotateAnimation(theView: rect, speed: speed, fromValue: CGFloat(.pi * 2.0 * Float(timeOffset) / 10.0), toValue: CGFloat(.pi * 2.0 * Float(timeOffset) / 10.0 + .pi * 2.0), option: opt)
} else {
rotateAnimation(theView: rect, speed: speed, fromValue: CGFloat(.pi * 2.0 * Float(timeOffset) / 10.0), toValue: CGFloat(.pi * 2.0 * Float(timeOffset) / 10.0 + .pi * 2.0))
// note that timeOffset is initialize to be 0.
}
}
你想要一个自定义的CAMediaTimingFunction,从0.5的斜率开始逐渐增加到1.0,我没有在这里优化贝塞尔曲线,你可以做你想要的曲线。
最后对你的动画功能进行一些调整:
func rotateAnimation(theView: UIView, speed: Float, duration: CFTimeInterval = 10.0, fromValue: CGFloat = CGFloat(0.0), toValue: CGFloat = CGFloat(.pi * 2.0), option: CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)) {
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.fromValue = fromValue
rotateAnimation.toValue = toValue
rotateAnimation.duration = duration
rotateAnimation.speed = speed
rotateAnimation.repeatCount = 1
rotateAnimation.delegate = self
rotateAnimation.timingFunction = option
theView.layer.add(rotateAnimation, forKey: nil)
}