I am using bezier path, shape layer and CABasicAnimation to draw view animately. But it draw view only single time. How to draw same bezier path multiple times after finished the previous one ?
This is the attached code for creating this type of waveform. Please check...
class ViewController: UIViewController {
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var graphView: UIView!
// MARK:- PROPERTIES
var movingPoint: CGFloat = 0.0
var startInterval: CGFloat = 10.0
var noOfIntervals: CGFloat = 0
var intervalWidth: CGFloat = 0
var pWaveWidth: CGFloat = 20.0
var qrsWaveWidth: CGFloat = 15
var tWaveWidth: CGFloat = 30
var gapBetweenTwoIntervals: CGFloat = 50
let shapeLayer = CAShapeLayer()
var bezierPath = UIBezierPath()
let animation = CABasicAnimation(keyPath: "strokeEnd")
override func viewDidLoad() {
super.viewDidLoad()
graphView.translatesAutoresizingMaskIntoConstraints = true
graphView.frame.size = CGSize(width: 100000, height: 150)
DispatchQueue.main.async {
self.graphView.layoutIfNeeded()
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
createGraph()
}
@objc func createGraph() {
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 2.0
_ = createBezierPath()
graphView.layer.addSublayer(shapeLayer)
}
@discardableResult
@objc func createBezierPath(isPathAlreadyCreated: Bool = false) -> UIBezierPath {
for _ in 0..<205 {
let path = UIBezierPath()
path.move(to: CGPoint(x: movingPoint, y: graphView.halfHeight))
path.addLine(to: CGPoint(x: startInterval, y: graphView.halfHeight))
// P Point Curve
let pWaveX = startInterval + pWaveWidth
path.addQuadCurve(to: CGPoint(x: pWaveX, y: graphView.halfHeight), controlPoint: CGPoint(x: pWaveX - 6.0, y: graphView.halfHeight - 30.0))
let gapBetweenPAndQRS: CGFloat = 20.0
path.addLine(to: CGPoint(x: (pWaveX + gapBetweenPAndQRS), y: graphView.halfHeight))
// QRS
let qrsStartPoint = pWaveX + gapBetweenPAndQRS
let qrsComplex = qrsStartPoint + qrsWaveWidth
let qrsComplexEndPoint = qrsComplex + (qrsWaveWidth / 2)
path.addLine(to: CGPoint(x: qrsStartPoint + (qrsWaveWidth / 2), y: graphView.halfHeight - 70.0))
path.addLine(to: CGPoint(x: qrsComplex, y: graphView.halfHeight + 40.0))
path.addLine(to: CGPoint(x: qrsComplexEndPoint, y: graphView.halfHeight))
let gapBetweenQRSAndTWave: CGFloat = 20.0
let tWaveStartPoint = qrsComplexEndPoint + gapBetweenQRSAndTWave
path.addLine(to: CGPoint(x: tWaveStartPoint, y: graphView.halfHeight))
// T Point Curve
let tWaveEndX = tWaveStartPoint + tWaveWidth
print(tWaveEndX)
path.addQuadCurve(to: CGPoint(x: tWaveEndX, y: graphView.halfHeight), controlPoint: CGPoint(x: tWaveEndX - 7.0, y: graphView.halfHeight - 30.0))
movingPoint = tWaveEndX
startInterval = tWaveEndX + gapBetweenTwoIntervals
path.addLine(to: CGPoint(x: startInterval, y: graphView.halfHeight))
bezierPath.append(path)
}
shapeLayer.path = bezierPath.cgPath
animation.fromValue = 0.0
animation.duration = 205 * 2
shapeLayer.add(animation, forKey: "PathAnimation")
return bezierPath
}
}