Использование UIViewPropertyAnimator для перемещения анимации по изогнутой траектории? - PullRequest
0 голосов
/ 12 октября 2018

У меня есть прерываемый переход, который управляется 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)

Пока эта анимация идет по правильному пути, однако анимация возвращается в исходное положение и не синхронизируется с аниматором свойств.

Есть предложения?

...