UIView使用SpringWithDamping进行动画制作

时间:2017-04-19 07:20:30

标签: core-animation

我创建了一个shaperLayer,并且该层的路径由bezierPath提供。代码如下:

    let shapeLayer = CAShapeLayer()
    let bezierPath = UIBezierPath()
    let bezierPath1 = UIBezierPath()

    shapeLayer.fillColor = UIColor.cyan.cgColor

    bezierPath.move(to: CGPoint.zero)
    bezierPath.addLine(to: CGPoint(x: 0, y: 50))
    bezierPath.addCurve(to: CGPoint(x: 140.935, y: 50), controlPoint1: CGPoint(x: 0, y: 50), controlPoint2: CGPoint(x: 87.340, y: 50))
    bezierPath.addCurve(to: CGPoint(x: 250.578, y: 50), controlPoint1: CGPoint(x: 198.5, y: 50), controlPoint2: CGPoint(x: 250.578, y: 50))
    bezierPath.addCurve(to: CGPoint(x: 375, y: 50), controlPoint1: CGPoint(x: 250.57, y: 50), controlPoint2: CGPoint(x: 299.064, y: 50))
    bezierPath.addLine(to: CGPoint(x: 375, y: 0))
    bezierPath.close()



    bezierPath1.move(to: CGPoint.zero)
    bezierPath1.addLine(to: CGPoint(x: 0, y: 81.5))
    bezierPath1.addCurve(to: CGPoint(x: 140.935, y: 139.099), controlPoint1: CGPoint(x: 0, y: 81.5), controlPoint2: CGPoint(x: 87.340, y: 81.5))
    bezierPath1.addCurve(to: CGPoint(x: 250.578, y: 139.09), controlPoint1: CGPoint(x: 198.5, y: 203.90), controlPoint2: CGPoint(x: 250.578, y: 139.09))
    bezierPath1.addCurve(to: CGPoint(x: 375, y: 81.5), controlPoint1: CGPoint(x: 250.57, y: 139.09), controlPoint2: CGPoint(x: 299.064, y: 81.5))
    bezierPath1.addLine(to: CGPoint(x: 375, y: 0))
    bezierPath1.close()

    shapeLayer.path = bezierPath1.cgPath
    self.view.layer.addSublayer(shapeLayer)

    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0, options: [], animations: {

            shapeLayer.path = bezierPath.cgPath
        }) { (finish) in

        }
    }

但动画不是我想要的。我期望的效果是这样的: good effect

实际效果是这样的: real effect

我不知道为什么。它没有弹跳效果。我觉得我错过了一些重要的东西,有没有人可以帮助我?

1 个答案:

答案 0 :(得分:0)

您需要使用Core Animation为路径设置动画,而不是您使用的UIView动画块。另一个问题是,您无法为CALayer路径值执行弹簧动画。因此,您必须使用关键帧动画(近似与关键帧的反弹),或接受正常的缓动类型。

示例:

class ViewController: UIViewController {

    let shapeLayer = CAShapeLayer()
    let bezierPath = UIBezierPath()
    let bezierPath1 = UIBezierPath()

    override func viewDidLoad() {
        super.viewDidLoad()

        shapeLayer.fillColor = UIColor.cyan.cgColor

        bezierPath.move(to: CGPoint.zero)
        bezierPath.addLine(to: CGPoint(x: 0, y: 50))
        bezierPath.addCurve(to: CGPoint(x: 140.935, y: 50), controlPoint1: CGPoint(x: 0, y: 50), controlPoint2: CGPoint(x: 87.340, y: 50))
        bezierPath.addCurve(to: CGPoint(x: 250.578, y: 50), controlPoint1: CGPoint(x: 198.5, y: 50), controlPoint2: CGPoint(x: 250.578, y: 50))
        bezierPath.addCurve(to: CGPoint(x: 375, y: 50), controlPoint1: CGPoint(x: 250.57, y: 50), controlPoint2: CGPoint(x: 299.064, y: 50))
        bezierPath.addLine(to: CGPoint(x: 375, y: 0))
        bezierPath.close()

        bezierPath1.move(to: CGPoint.zero)
        bezierPath1.addLine(to: CGPoint(x: 0, y: 81.5))
        bezierPath1.addCurve(to: CGPoint(x: 140.935, y: 139.099), controlPoint1: CGPoint(x: 0, y: 81.5), controlPoint2: CGPoint(x: 87.340, y: 81.5))
        bezierPath1.addCurve(to: CGPoint(x: 250.578, y: 139.09), controlPoint1: CGPoint(x: 198.5, y: 203.90), controlPoint2: CGPoint(x: 250.578, y: 139.09))
        bezierPath1.addCurve(to: CGPoint(x: 375, y: 81.5), controlPoint1: CGPoint(x: 250.57, y: 139.09), controlPoint2: CGPoint(x: 299.064, y: 81.5))
        bezierPath1.addLine(to: CGPoint(x: 375, y: 0))
        bezierPath1.close()

        shapeLayer.path = bezierPath1.cgPath
        view.layer.addSublayer(shapeLayer)
        animateThing()
    }

    func animateThing() {
        guard shapeLayer.animation(forKey: "path") == nil else {
            return
        }
        let myAnimation = CABasicAnimation(keyPath: "path")
        myAnimation.duration = 0.5
        myAnimation.fromValue = bezierPath1.cgPath
        myAnimation.toValue = bezierPath.cgPath
        myAnimation.isRemovedOnCompletion = true
        myAnimation.fillMode = kCAFillModeBoth

        shapeLayer.add(myAnimation, forKey: "path")
        shapeLayer.path = bezierPath.cgPath
    }
}