I have UIBezierPath array that created from touchesBegan and touchesMoved point. I want animate the draw of them on the screen.
What is the best way to do that without iterate each bezier and call setNeedsDisplay()?
thanks
override func draw(_ rect: CGRect) {
for bezier in beziers{
bezier.stroke()
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
let cgPoint = touches.first!.location(in: self)
let bezierPath = ColorBezierPath() // subclass of UIBezierPath
bezierPath.lineWidth = lineWidth
bezierPath.color = color
bezierPath.move(to: cgPoint)
beziers.append(bezierPath)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
let cgPoint = touches.first!.location(in: self)
let bezierPath = beziers.last
bezierPath?.addLine(to: cgPoint)
setNeedsDisplay()
}
Your best bet would be to use CAShapeLayer
. It takes a path and various other settings. To animate it, just animate its strokeEnd
property from 0.0
to 1.0
. That will create the effect of drawing the path from start to finish given whatever animation timing parameters you want:
let shapeLayer = CAShapeLayer() // strokeEnd's model value is 1.0 by default
shapeLayer.frame = containerLayer.bounds
shapeLayer.path = bezierPath.cgPath
containerLayer.addSublayer(shapeLayer)
let strokeEndAnimation = CABasicAnimation(keyPath: "strokeEnd")
strokeEndAnimation.duration = 2.0
strokeEndAnimation.fromValue = 0.0
shapeLayer.add(strokeEndAnimation, forKey: "strokeEndAnimation")