I wish to animate the color fill of a section of a pie chart. I create the pie chart by creating a UIBezierPath()
for each piece of the pie and then use the addArc
method to specify the size/constraints of the arc. To animate the pie chart segment, I want the color fill of the arc to animate from the center of the circle to the radius end. However, I am having trouble. I heard the strokeEnd
keyPath
animated from 0
to 1
should work, but there is no animation happening on the arcs (the arcs are just appearing at app launch).
let rad = 2 * Double.pi
let pieCenter: CGPoint = CGPoint(x: frame.width / 2, y: frame.height / 2)
var start: Double = 0
for i in 0...data.count - 1 {
let size: Double = Double(data[i])! / 100 // the percentege of the circle that the given arc will take
let end: Double = start + (size * rad)
let path = UIBezierPath()
path.move(to: pieCenter)
path.addArc(withCenter: pieCenter, radius: frame.width / 3, startAngle: CGFloat(start), endAngle: CGFloat(end), clockwise: true)
start += size * rad
let lineLayer = CAShapeLayer()
lineLayer.bounds = self.bounds
lineLayer.position = self.layer.position
lineLayer.path = path.cgPath
lineLayer.strokeColor = UIColor.white.cgColor
lineLayer.fillColor = colors[i]
lineLayer.lineWidth = 0
self.layer.addSublayer(lineLayer)
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
animation.fillMode = kCAFillModeForwards
animation.fromValue = pieCenter
animation.toValue = frame.width / 3 // radius
animation.duration = 2.5
lineLayer.add(animation, forKey: nil)
}
I've seen a solution to a similar problem here, but it does not work for the individual arcs.
In order to ensure a smooth, clockwise animation of the pie chart, you must perform the following steps in order:
CAShapeLayer
self.layer.addSublayer(parentLayer)
In a nutshell, the code will look like this:
// Code above this line adds the pie chart slices to the parentLayer
for layer in parentLayer.sublayers! {
// Code in this block creates and animates the same mask for each layer
}
Each animation applied to each pie slice will be a strokeEnd
keypath animation from 0
to 1
. When creating the mask, be sure its fillColor
property is set to UIColor.clear.cgColor
.