円を描く

https://stackoverflow.com/questions/26578023/animate-drawing-of-a-circle

https://qiita.com/wilshar10/items/1782bdbf9f0cc665ccf5

f:id:hayateasdf:20171129190617g:plain

import UIKit

class TestCircleViewController: UIViewController {

    @IBOutlet weak var parentView: UIView!
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let circleView = CircleView(frame: parentView.bounds)
        parentView.addSubview(circleView)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

struct Segment {
    var color: UIColor
    var value: CGFloat
}
class CircleView: UIView {
    var circleLayers: [CAShapeLayer]!
    let segments = [
        Segment(color: UIColor.green, value: 10),
        Segment(color: UIColor.lightGray, value: 20),
        Segment(color: UIColor.blue, value: 30),
        Segment(color: UIColor.red, value: 40),
    ]
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.gray
        
        let startAngle = -CGFloat(Float.pi * 0.5)
        let endAngle = startAngle + CGFloat(Float.pi * 2.0)
        
        let lineWidth = frame.size.width / 5
        let radius = (frame.size.width - lineWidth) / 2
        let circlePath = UIBezierPath(
            arcCenter: CGPoint(x: frame.size.width / 2, y: frame.size.height / 2),
            radius: radius,
            startAngle: startAngle,
            endAngle: endAngle,
            clockwise: true)
        
        let valueCount = segments.reduce(0) { $0 + $1.value }
        
        var start: CGFloat = 0.0
        self.circleLayers = segments.map {
            let end = start + ($0.value / valueCount)
            let circle = CAShapeLayer()
            circle.path = circlePath.cgPath
            circle.fillColor = UIColor.clear.cgColor
            circle.strokeColor = $0.color.cgColor
            circle.lineWidth = lineWidth
            circle.strokeStart = start
            circle.strokeEnd = end
            layer.addSublayer(circle)
            start = end
            
            return circle
        }
        
        animationCircle(duration: 0.7)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError()
    }
    
    func animationCircle(duration: TimeInterval) {
        for item in self.circleLayers {
            let animation = CABasicAnimation(keyPath: "strokeEnd")
            animation.duration = duration
            animation.fromValue = 0
            animation.toValue = 1
            animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
            
            item.strokeEnd = 1.0
            item.add(animation, forKey: "animateCircle")
        }
    }
}