2017-04-19 78 views
1

我創建了一個shaperLayer,並且圖層的路徑由bezierPath提供。代碼如下:UIView動畫使用SpringWithDamping

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

我不知道爲什麼。它沒有反彈效果。我thik我錯過了重要的東西,有沒有人可以幫助我?

回答

0

您需要使用核心動畫來創建路徑的動畫,而不是使用的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 
    } 
}