title: Add Colour Gradient to Circular Progress Bar iOS
body: <p>I am having difficulty adding a colour gradient to my circular progress bar</p>
  
  <p><a href="https://i.stack.imgur.com/aDyEN.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/aDyEN.png" alt="enter image description here"></a></p>
  
  <p>My setup:</p>
  
  <ol>
  <li>Storyboard: ViewController with an empty view designated as the Class CircularProgressBar</li>
  <li>Custom class for the CircularProgressBar</li>
  </ol>
  
  <p>Steps Taken:</p>
  
  <ol>
  <li>I am able to load circular progress bar</li>
  <li>In earlier attempts I created a gradient shape layer &amp; set it to be masked by the bounds of the BarLayer, however the gradient shape layer draw a rectangle starting from the centre of my circle &amp; extend to the bottom right so only that portion of the BarLayer would have a gradient</li>
  <li>When I moved the origin of the gradient layer rectangle it shifted the Barlayer off the TrackLayer with it</li>
  </ol>
  
  <p>How do I:</p>
  
  <p>Have the gradient layer cover the entire circular progress bar &amp; mask it to the BarLayer</p>
  
  <pre><code>class CircularProgressBar: UIView {
  
  let shapeLayer = CAShapeLayer()
  let trackLayer = CAShapeLayer()
  
  override init(frame: CGRect) {
  super.init(frame: frame)
      addProgressBar(radius: 5, progress: 0)
  }
  
  required init?(coder aDecoder: NSCoder) {
  super.init(coder: aDecoder)
      addProgressBar(radius: 5, progress: 0)
  }
  
  func addProgressBar(radius: CGFloat, progress: CGFloat) {
  
      let lineWidth = radius*0.080
  
      let circularPath = UIBezierPath(arcCenter: CGPoint(x: bounds.midX, y: bounds.midY), radius: radius, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true)
  
      //TrackLayer
      trackLayer.path = circularPath.cgPath
      trackLayer.fillColor = UIColor.lightGray.cgColor
      trackLayer.strokeColor = UIColor.clear.cgColor
      trackLayer.opacity = 0.5
      trackLayer.lineWidth = lineWidth
      trackLayer.lineCap = CAShapeLayerLineCap.round
  
      //BarLayer
      shapeLayer.path = circularPath.cgPath
      shapeLayer.fillColor = UIColor.clear.cgColor
      shapeLayer.strokeColor = UIColor.systemGreen.cgColor
      shapeLayer.lineWidth = lineWidth
      shapeLayer.strokeEnd = 0
      shapeLayer.lineCap = CAShapeLayerLineCap.round
  
  
  
      //Rotate Shape Layer
      shapeLayer.transform = CATransform3DMakeRotation(-CGFloat.pi/2, 0, 0, 1)
  
  //Shape Shadow
      shapeLayer.shadowColor = UIColor.black.cgColor
      shapeLayer.shadowOffset = CGSize(width: -7, height: 7)
      shapeLayer.shadowRadius = 1
      shapeLayer.shadowOpacity = 0.5
  
      //Animation
      loadProgress(percentage: progress)
  
      //LoadLayers
      layer.addSublayer(trackLayer)
      layer.addSublayer(shapeLayer)
  
  }  
  func loadProgress(percentage: CGFloat) {
  
      let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
      basicAnimation.fromValue = 0
      basicAnimation.duration = 2
      basicAnimation.fillMode = CAMediaTimingFillMode.forwards
      basicAnimation.isRemovedOnCompletion = false
      shapeLayer.strokeEnd = percentage
      shapeLayer.add(basicAnimation, forKey: "basicStroke")
  
  }
  </code></pre>
  
  <p>ViewController</p>
  
  <pre><code>class HomeViewController: UIViewController {
  
  @IBOutlet weak var containerView: UIView!
  
  
  var circularProgressBar = CircularProgressBar()
  var radius: CGFloat!
  var progress: CGFloat!
  
  var answeredCorrect = 0
  var totalQuestions = 0
  
  
  override func viewDidLoad() {
      super.viewDidLoad()
  
      answeredCorrect = 50
      totalQuestions = 100
  
      //Configure Progress Bar
      radius = (containerView.frame.height)/2.60
      progress = CGFloat(answeredCorrect) / CGFloat (totalQuestions)
      circularProgressBar.addProgressBar(radius: radius, progress: progress)
      circularProgressBar.center = containerView.center
  
      //Adding view
      containerView.addSubview(circularProgressBar)
  
  
  }  
  }
  </code></pre>