Search code examples
swiftcore-animation

Draw A Path with Animation


I want to draw a path with animation in my application I used the code below but there is no animation and it only adds the result of the path to View even when I make the duration longer than normal.

let animation = CABasicAnimation(keyPath: "strokeEnd")
let layer = CAShapeLayer()
let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 38.5, y: 88.5))
bezierPath.addCurve(to: CGPoint(x: 86.5, y: 88.5), controlPoint1: CGPoint(x: 41.5, y: 88.5), controlPoint2: CGPoint(x: 86.5, y: 88.5))
bezierPath.addLine(to: CGPoint(x: 86.5, y: 64.5))
bezierPath.addLine(to: CGPoint(x: 145.5, y: 64.5))
UIColor.black.setStroke()
bezierPath.lineWidth = 1
bezierPath.stroke()

layer.path = bezierPath.cgPath
layer.strokeEnd = 0
layer.lineWidth = 1
layer.strokeColor = UIColor.gray.cgColor
layer.fillColor = UIColor.black.cgColor

animation.toValue = 1
animation.duration = 20 // seconds
layer.add(animation, forKey: "Line")
self.view.layer.addSublayer(layer)

I don't know how to make it animate


Solution

  • This works on my machine, here is the full class, and code :

    https://github.com/Shah3r/testAnim

    enter image description here

    import UIKit
    
    class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        //Use CATransaction
        CATransaction.begin()
    
        //Set Layer
        let layer = CAShapeLayer()
        layer.lineWidth = 3
        layer.strokeColor = UIColor.red.cgColor
        layer.fillColor = UIColor.black.cgColor
    
        //Set Bezier Path
        let bezierPath = UIBezierPath()
        bezierPath.move(to: CGPoint(x: 38.5, y: 88.5))
        bezierPath.addCurve(to: CGPoint(x: 86.5, y: 88.5), controlPoint1: CGPoint(x: 41.5, y: 88.5), controlPoint2: CGPoint(x: 86.5, y: 88.5))
        bezierPath.addLine(to: CGPoint(x: 86.5, y: 64.5))
        bezierPath.addLine(to: CGPoint(x: 145.5, y: 64.5))
    
        //Set Animation
         let animation = CABasicAnimation(keyPath: "strokeEnd")
        animation.fromValue = 0.0
        animation.toValue = 1
        animation.duration = 7.0 // seconds
    
      //Completion Block
        CATransaction.setCompletionBlock{
            print("Animation completed")
        }
    
        //Add path and animation
        layer.path = bezierPath.cgPath
        layer.add(animation, forKey: "Line")
        CATransaction.commit()
    
        self.view.layer.addSublayer(layer)
     }
    }