Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Circular Gradient

Tags:

ios

swift

I have a task to draw the line with a circular gradient (colour should change by the circle) and then add animation. Now I draw 360 layers with a certain interval and different colours.

var colours: [UIColor] = [UIColor]()
var startAngle = CGFloat(-0.5 * Double.pi)
var index = 0

func drawLayers() {
    let smallAngle = (1.5 * CGFloat.pi - (-0.5 * CGFloat.pi)) / 360

    if index < colours.count { //colours.count = 360
        let endAngle = startAngle + smallAngle
        let circlePath = UIBezierPath(arcCenter: .init(x: 100, y: 100), radius: 100, startAngle: startAngle, endAngle: endAngle, clockwise: true)
        startAngle = endAngle
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = circlePath.cgPath

        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.strokeColor = colours[index].cgColor
        shapeLayer.lineWidth = 8

        view.layer.addSublayer(shapeLayer)

        index += 1

        Timer.scheduledTimer(
            withTimeInterval: 0.004,
            repeats: false) { (_) in
                self.drawLayers()
        }
    }
}

Something like that but with linear animation

enter image description here

Can anyone tell me how to do it right?

like image 623
Dima Paliychuk Avatar asked Feb 01 '26 13:02

Dima Paliychuk


1 Answers

iOS has circular (conic) gradients built in now. So I would just ask for the gradient, once, and then animate a single path used as a mask. That’s just two layers, much less work, true animation, and a true gradient.

Example:

enter image description here

Here's my test code; change the colors and numbers as desired:

    let grad = CAGradientLayer()
    grad.type = .conic
    grad.colors = [UIColor.red.cgColor, UIColor.green.cgColor, UIColor.red.cgColor]
    grad.startPoint = CGPoint(x: 0.5, y: 0.5)
    grad.frame = CGRect(x: 100, y: 100, width: 200, height: 200)
    self.view.layer.addSublayer(grad)
    let c = CAShapeLayer()
    let p = UIBezierPath(ovalIn: CGRect(x: 20, y: 20, width: 160, height: 160))
    c.path = p.cgPath
    c.fillColor = UIColor.clear.cgColor
    c.strokeColor = UIColor.black.cgColor
    c.lineWidth = 8
    grad.mask = c
    c.strokeEnd = 0

To make the animation happen, just say:

    c.strokeEnd = 1
like image 108
matt Avatar answered Feb 03 '26 06:02

matt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!