I'm creating a crude animation of a changing smile using Core Animation. I'm using CAShapeLayer, CAKeyframeAnimation, and UIBezierPath objects to create the paths that change/animate. The problem I'm seeing is that the original path drawn (i.e. the first keyframe in the set of keyframe values) remains throughout the animation. I was expecting it to only be there for the start of the animation and then animate to the next keyframe value...however, it remains and I would like to get rid of it.
Here are some code snippets of my work so far:
let width: CGFloat = 240
let height: CGFloat = 120
let shapeLayer = CAShapeLayer()
shapeLayer.frame = CGRect(x: 0, y: 0,
width: width, height: height)
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 2
shapeLayer.fillColor = UIColor.clear.cgColor
view1.layer.addSublayer(shapeLayer)
let keyframeAnimation = CAKeyframeAnimation(keyPath: "path")
keyframeAnimation.values =
[
smile(state: .expressionless).cgPath,
smile(state: .grin).cgPath,
smile(state: .expressionless).cgPath,
smile(state: .frown).cgPath,
smile(state: .expressionless).cgPath
]
keyframeAnimation.duration = 5
keyframeAnimation.calculationMode = .cubic
// keeps the animation in its final state and doesn't revert to its original shape
keyframeAnimation.isRemovedOnCompletion = false
keyframeAnimation.fillMode = CAMediaTimingFillMode.forwards
shapeLayer.add(keyframeAnimation, forKey: nil)
and the smile code function and related enum:
enum SmileState {
case grin
case frown
case expressionless
case veryhappy
}
func smile(state: SmileState) -> UIBezierPath {
let curve = UIBezierPath()
if (state == .frown) {
curve.move(to: CGPoint(x: 0, y: 110))
curve.addQuadCurve(to: CGPoint(x: 240, y: 110), controlPoint: CGPoint(x: 120, y: -290))
}
else if (state == .expressionless) {
curve.move(to: CGPoint(x: 0, y: 60))
curve.addQuadCurve(to: CGPoint(x: 240, y: 60), controlPoint: CGPoint(x: 120, y: 60))
}
else if (state == .grin) {
curve.move(to: CGPoint(x: 0, y: 10))
curve.addQuadCurve(to: CGPoint(x: 240, y: 10), controlPoint: CGPoint(x: 120, y: 350))
}
curve.close()
return curve
}
Any suggestions on what I could do to remove that "expressionless" path as soon as the animation starts?