Search code examples
iosswiftcalayeruibezierpathcashapelayer

How to draw PieChart, Obtained Marks fill with some colour out of Total Marks without 3rd party library iOS Swift


I want like this

output look like this

Any code example will be appreciated


Solution

  • Here is a starting point ... created a circular progress view for your help

    import UIKit
    public class CircularProgressView: UIView {
      // First create two layer properties
      private lazy var circleLayer : CAShapeLayer = {
        let shape = CAShapeLayer()
        shape.fillColor = UIColor.clear.cgColor
        shape.lineCap = .round
        shape.lineWidth = 30.0
        shape.strokeColor = #colorLiteral(red: 0.7999292612, green: 0.8000453115, blue: 0.7999040484, alpha: 1)
        return shape
    
      }()
    
      private lazy var progressLayer : CAShapeLayer = {
        let progress = CAShapeLayer()
        progress.fillColor = UIColor.clear.cgColor
       // progress.lineCap = .round
           progress.lineWidth = 30.0
           progress.strokeEnd = 0
           progress.strokeColor = #colorLiteral(red: 0.07347138971, green: 0.5590900779, blue: 0.8216868043, alpha: 1)
        return progress
      }()
    
    
      override init(frame: CGRect) {
        super.init(frame: frame)
        createCircularPath()
      }
      required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        createCircularPath()
      }
    
    
     private func createCircularPath() {
    
        updatePath()
        layer.addSublayer(circleLayer)
        layer.addSublayer(progressLayer)
      }
      public override func layoutSubviews() {
        updatePath()
      }
    
      private func updatePath() {
        let circularPath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: 80, startAngle: -.pi / 2, endAngle: 3 * .pi / 2, clockwise: true)
    
           circleLayer.path = circularPath.cgPath
           progressLayer.path = circularPath.cgPath
      }
    
    }
    public extension CircularProgressView {
      func progressAnimation(_ percentage:Float) {
    
        let circularProgressAnimation = CABasicAnimation(keyPath: "strokeEnd")
        circularProgressAnimation.duration = 1
        circularProgressAnimation.toValue = Float( percentage / 100 )
        circularProgressAnimation.fillMode = .forwards
        circularProgressAnimation.isRemovedOnCompletion = false
        progressLayer.add(circularProgressAnimation, forKey: "progressAnim")
      }
    }
    

    enter image description here