So I have a bar chart where each bar is a CALayer. I want to animate each layer with a different delay.
private func drawBar(xPos: CGFloat, yPos: CGFloat, color: UIColor) {
// create animation
let animation = CABasicAnimation(keyPath: "bounds.size.height")
animation.beginTime = CACurrentMediaTime() + StaticVars.delay
animation.fromValue = 0
animation.toValue = mainLayer.frame.height - bottomSpace - yPos
animation.duration = 2.0
StaticVars.delay += 0.1
// create bar
let barLayer = CALayer()
barLayer.anchorPoint = CGPoint(x: 1, y: 1)
barLayer.frame = CGRect(x: xPos, y: yPos, width: barWidth, height: mainLayer.frame.height - bottomSpace - yPos)
barLayer.backgroundColor = color.cgColor
barLayer.add(animation, forKey: nil)
mainLayer.addSublayer(barLayer)
}
This works well, but there is one issue: the chart is already present on the screen, than it waits for the delay (0.1) than it starts animating each layer with a delay.
I can't understand why the chart is already showing. What I want is when the app appears on the screen the bars should not be visible, just after the first delay should the chart start animating.
If you want the layer to appear to have the fromValue
for the time before it begins (as set using the beginTime
) you can configure it to fill "backwards" by setting the fillMode
to .backwards
:
animation.fillMode = .backwards
Without this, the animation will display the model value (the height of the actual frame of the layer) for all times before the beginTime and after beginTime + duration:
With this change, the animation will fill any value before the begin time with the fromValue
(by clamping any time before the begin time to the start of the animation):