Reputation:
I'm having a view that draws 2 layers;
Now when I switch my path I want to animate both layers at the same time. So to do that I first had 2 separate layers and added an animation to each one of them. That worked, but I didn't like the fact that I had to write the animation for each one of them.
That's why I decided to create a CAShapeLayer subclass and move the gradient into the line layer so in terms of hierarchy it looks like this;
In code;
class LineLayer: CAShapeLayer {
// Configuration
private var configuration: ChartConfiguration!
// Layers
private var backgroundLayer: CAGradientLayer!
init(configuration: ChartConfiguration) {
super.init()
self.configuration = configuration
configureLayers()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func configureLayers() {
addLineLayer()
addBackgroundLayer()
}
private func addLineLayer() {
self.fillColor = UIColor.clear.cgColor
self.strokeColor = configuration.lineColor
self.lineWidth = configuration.lineWidth
}
private func addBackgroundLayer() {
backgroundLayer = CAGradientLayer()
backgroundLayer.anchorPoint = CGPoint(x: 0, y: 0)
backgroundLayer.colors = [UIColor.systemGreen.withAlphaComponent(0.24).cgColor, UIColor.systemGreen.withAlphaComponent(0).cgColor]
backgroundLayer.startPoint = CGPoint(x: 0, y: 0)
backgroundLayer.endPoint = CGPoint(x: 0, y: 1)
self.addSublayer(backgroundLayer)
}
public func updateBackgroundLayer(frame: CGRect, mask: CAShapeLayer) {
backgroundLayer.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
backgroundLayer.mask = mask
}
}
Then I animated the parent (line) and thought the children (gradient) would move along. Unfortunately this doesn't happen. My animation code looks like this;
lineLayer = LineLayer(configuration: configuration)
lineLayer.path = linePath
self.layer.addSublayer(lineLayer)
private func addPathAnimation() {
let animation = CABasicAnimation(keyPath: "path")
animation.duration = configuration.animationDuration
animation.fromValue = layer.path != nil ? layer.path : linePath
animation.toValue = path
animation.timingFunction = configuration.animationCurve
layer.add(animation, forKey: nil)
layer.path = path
}
Is it possible to animate the children when only animating the parent? Or do I just have to stick with separate layers added to the view and animate each one of them?
Upvotes: 2
Views: 1101
Reputation: 535139
Is it possible to animate the children when only animating the parent?
Yes (if I'm understanding the question correctly). You add
to the parent a CAAnimationGroup. That group coordinates multiple child CAAnimations. Assuming these are some kind of property animation, the keyPath
for each child animation can be a property of the parent or a property of any of its child sublayers (using the notation "sublayers.name.property"
, where name
is the value of the child's name
property).
Upvotes: 1