Swift: Gradient along the bezier path (using CALayers)

I have a relatively simple implementation of the progress view created with CALayer objects. The very idea of ​​progress is a subpoint of UIView.

Here is the code that sets the execution ring:

self.progressRingLayer = CAShapeLayer() let innerRect = CGRectInset(bounds, CGFloat(self.lineWidth) / 2, CGFloat(self.lineWidth) / 2) let innerPath = UIBezierPath(ovalInRect: innerRect) self.progressRingLayer.path = innerPath.CGPath self.progressRingLayer.fillColor = UIColor.clearColor().CGColor self.progressRingLayer.strokeColor = kProgressColor.CGColor self.progressRingLayer.anchorPoint = CGPointMake(0.5, 0.5) self.progressRingLayer.transform = CATransform3DRotate(self.progressRingLayer.transform, (CGFloat(M_PI))*1, 0, 0, 1) self.progressRingLayer.lineCap = kCALineCapRound self.progressRingLayer.lineWidth = CGFloat(self.lineWidth) self.layer.addSublayer(self.progressRingLayer) 

What I'm trying to do now is add a gradient to the progressRingLayer that follows (or bends) with the path. I managed to add a linear gradient to the fill, but not just the path.

Here is an example of what effect I want:

enter image description here

So far, everything I've found requires a bunch of extra steps with CoreGraphics and CGContext, which don't quite match my implementation. Any help would be great, thanks!

+5
source share
1 answer

What I would do is draw a gradient layer and then draw on top of that layer, which is black with the arc removed.

Here is my attempt at an approximate image that you provided (I omitted the white mark in the center, but this is trivial):

enter image description here

And here is the code that generated it:

 let r = CGRectMake(100,100,130,100) let g = CAGradientLayer() g.frame = r let c1 = UIColor( red: 151.0/255.0, green: 81.0/255.0, blue: 227.0/255.0, alpha: 1) let c2 = UIColor( red: 36.0/255.0, green: 176.0/255.0, blue: 233.0/255.0, alpha: 1) g.colors = [c1.CGColor as AnyObject, c2.CGColor as AnyObject]; self.view.layer.addSublayer(g) let percent = CGFloat(0.64) // percentage of circle UIGraphicsBeginImageContextWithOptions(r.size, false, 0) let con = UIGraphicsGetCurrentContext() CGContextFillRect(con, CGRect(origin: CGPoint(), size: r.size)) CGContextSetLineWidth(con, 5) CGContextSetLineCap(con, kCGLineCapRound) CGContextSetBlendMode(con, kCGBlendModeClear) let pi = CGFloat(M_PI) CGContextAddArc(con, r.size.width/2.0, r.size.height/2.0, 30, -pi/2.0, -pi/2.0 + percent*pi*2.0, 0) CGContextStrokePath(con) let im = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() let b = CALayer() b.frame = r b.contents = im.CGImage self.view.layer.addSublayer(b) 

The gradient level (the first part of the code) is just a service offer. If this is not the gradient you want, you can create your own. You can draw it in Photoshop and use the image as the content of the gradient layer. Or you can make the layer “angular” in your code using third-party code, for example https://github.com/paiv/AngleGradientLayer . The purpose of the example is simply to show how you can “erase” an arc in a black layer to reveal the gradient hidden behind it and, thus, draw a gradient.

+6
source

Source: https://habr.com/ru/post/1211033/


All Articles