CAShapeLayer and CABasicAnimation.
The problem is that there is no guarantee that the animationDidStop callback method will be called before the layer’s appearance is reset.
There are a couple of ways to fix this, the following way just involves adding some extra code without changing your existing code.
CATransaction.setCompletionBlock {
CATransaction.setDisableActions(true) // Fix code 1
layer.fillColor = UIColor.red.cgColor // Changing color will flickering, if not set fix codes.
}
let animation = CABasicAnimation(keyPath: "path")
animation.isRemovedOnCompletion = false // Fix code 2
animation.fillMode = .forwards // Fix code 3