0

Hey I have a circle with a gradient progress like so:

enter image description here

Code as follows:

@IBDesignable class DashboardMetricCircleView: UIView {

    enum Constants {
        static let duration: Double = 1.5
        static let lineWidth: CGFloat = 4.0
    }

    let circleBgLayer: CAShapeLayer = CAShapeLayer()
    let circleProgressLayer: CAShapeLayer = CAShapeLayer()
    let gradientLayer: CAGradientLayer = CAGradientLayer()

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    private func setup() {
        layer.addSublayer(circleBgLayer)
        layer.addSublayer(gradientLayer)

        circleBgLayer.shouldRasterize = true
        circleBgLayer.rasterizationScale = UIScreen.main.scale * 2.0
        circleBgLayer.strokeColor = Theme.background.cgColor
        circleBgLayer.fillColor = nil
        circleBgLayer.lineWidth = Constants.lineWidth

        circleProgressLayer.shouldRasterize = true
        circleProgressLayer.rasterizationScale = UIScreen.main.scale * 2.0
        circleProgressLayer.strokeColor = UIColor.black.cgColor
        circleProgressLayer.lineCap = .round
        circleProgressLayer.fillColor = nil
        circleProgressLayer.lineWidth = Constants.lineWidth
        circleProgressLayer.strokeStart = 0.0
        circleProgressLayer.strokeEnd = 0.0

        gradientLayer.mask = circleProgressLayer
        gradientLayer.shouldRasterize = true
        gradientLayer.rasterizationScale = UIScreen.main.scale * 2.0
        gradientLayer.colors = [
            UIColor.red.cgColor,
            UIColor.yellow.cgColor
        ]
    }

    func animate(progress: CGFloat) {
        let animateStroke = CABasicAnimation(keyPath: "strokeEnd")
        animateStroke.toValue = progress
        animateStroke.duration = Constants.duration
        animateStroke.isRemovedOnCompletion = false
        animateStroke.fillMode = .forwards
        circleProgressLayer.add(animateStroke, forKey: "MyAnimation")
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        circleBgLayer.frame = bounds
        circleProgressLayer.frame = bounds
        gradientLayer.frame = bounds

        let centerPt = CGPoint(x: bounds.width / 2.0, y: bounds.width / 2.0)
        let radius = bounds.width / 2.0 - Constants.lineWidth / 2.0
        circleBgLayer.path = UIBezierPath(arcCenter: centerPt, radius: radius, startAngle: 0.0, endAngle: CGFloat.pi * 2.0, clockwise: true).cgPath
        circleProgressLayer.path = UIBezierPath(arcCenter: centerPt, radius: radius, startAngle: CGFloat.pi * 3/2, endAngle: CGFloat.pi * 7/2, clockwise: true).cgPath
    }

}

I want to make the gradient evenly distributed. Yellow should start at 12 o'clock and it should gradually turn into red when it gets to the end of a single rotation. How can I configure the gradient to do this?

Kex
  • 8,023
  • 9
  • 56
  • 129
  • Are you just taking about rotating the gradient by 180 degrees? – stevenpcurtis Apr 12 '19 at 06:41
  • If I understand this question correctly you want something like what was asked here: https://stackoverflow.com/questions/44262374/swift-rainbow-colour-circle If this is the case you might want to mark this question as a duplicate. If it is not the case you might want to explain a bit better what the result you are looking for is. Might I suggest adding an image of the expected result? – Francesco D.M. Apr 12 '19 at 08:32
  • Please check [Swift: rainbow colour circle ](https://stackoverflow.com/questions/44262374/swift-rainbow-colour-circle) – dengApro Apr 12 '19 at 09:00

0 Answers0