我有一个由UIViewPropertyAnimator驱动的可中断过渡,我想为沿其目的地的非线性路径设置视图动画。
进行一些研究,我发现执行此操作的方法是使用:
CAKeyframeAnimation
。但是,我在协调动画方面遇到问题,在CAKeyframeAnimation填充模式方面也遇到问题。
即使我将其设置为前进,它也似乎是反向的。
下面是贝塞尔曲线路径:
let bezierPath = self.generateCurve(from: CGPoint(x: self.itemStartFrame.midX, y: self.itemStartFrame.midY), to: CGPoint(x: self.itemEndFrame.midX, y: self.itemEndFrame.midY), bendFactor: 1, thickness: 1)
func generateCurve(from: CGPoint, to: CGPoint, bendFactor: CGFloat, thickness: CGFloat) -> UIBezierPath {
let center = CGPoint(x: (from.x+to.x)*0.5, y: (from.y+to.y)*0.5)
let normal = CGPoint(x: -(from.y-to.y), y: (from.x-to.x))
let normalNormalized: CGPoint = {
let normalSize = sqrt(normal.x*normal.x + normal.y*normal.y)
guard normalSize > 0.0 else { return .zero }
return CGPoint(x: normal.x/normalSize, y: normal.y/normalSize)
}()
let path = UIBezierPath()
path.move(to: from)
let midControlPoint: CGPoint = CGPoint(x: center.x + normal.x*bendFactor, y: center.y + normal.y*bendFactor)
let closeControlPoint: CGPoint = CGPoint(x: midControlPoint.x + normalNormalized.x*thickness*0.5, y: midControlPoint.y + normalNormalized.y*thickness*0.5)
let farControlPoint: CGPoint = CGPoint(x: midControlPoint.x - normalNormalized.x*thickness*0.5, y: midControlPoint.y - normalNormalized.y*thickness*0.5)
path.addQuadCurve(to: to, controlPoint: closeControlPoint)
path.addQuadCurve(to: from, controlPoint: farControlPoint)
path.close()
return path
}
路径可视化:
let shapeLayer = CAShapeLayer()
shapeLayer.path = bezierPath.cgPath
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 2
containerView.layer.addSublayer(shapeLayer)
这是CAKeyframeAnimation,它位于UIViewPropertyAnimator中
let curvedPathAnimation = CAKeyframeAnimation(keyPath: "position")
curvedPathAnimation.path = bezierPath.cgPath
curvedPathAnimation.fillMode = kCAFillModeForwards
curvedPathAnimation.calculationMode = kCAAnimationPaced
curvedPathAnimation.duration = animationDuration
self.attatchmentView.layer.add(curvedPathAnimation, forKey: nil)
到目前为止,此动画沿正确的路径进行,但是该动画会返回到其初始位置,并且与属性动画师不同步。
有什么建议吗?