Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing A Circle With Gradient Stroke

I am working on a task in which I must create a circle with no fill, but a gradient stroke. For reference, here is the end result I am after;

Circle with gradient stroke

Given other occurrences with the app, I am drawing my circle like so;

let c = UIGraphicsGetCurrentContext()!
c.saveGState()
let clipPath: CGPath = UIBezierPath(roundedRect: converted_rect, cornerRadius: converted_rect.width / 2).cgPath
c.addPath(clipPath)
c.setLineWidth(9.0)
c.setStrokeColor(UIColor.blue.cgColor)
c.closePath()
c.strokePath()
c.restoreGState()
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

This results in a circle with a blue stroke. Despite many searches around SO, I'm struggling to figure out how I'd replace that setStrokeColor with a gradient, rather than a blue color. My most success came from creating a CAGradientLayer, then masking it with a CAShapeLayer created from the path, but I was only able to create a filled circle, not a hollow circle.

Thank you!

like image 863
ZbadhabitZ Avatar asked Aug 13 '17 17:08

ZbadhabitZ


1 Answers

The basic idea is to use your path as a clipping path, then draw the gradient.

let c = UIGraphicsGetCurrentContext()!
let clipPath: CGPath = UIBezierPath(ovalIn: converted_rect).cgPath

c.saveGState()
c.setLineWidth(9.0)
c.addPath(clipPath)
c.replacePathWithStrokedPath()
c.clip()

// Draw gradient
let colors = [UIColor.blue.cgColor, UIColor.red.cgColor]
let offsets = [ CGFloat(0.0), CGFloat(1.0) ]
let grad = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors as CFArray, locations: offsets)
let start = converted_rect.origin
let end = CGPoint(x: converted_rect.maxX, y: converted_rect.maxY)
c.drawLinearGradient(grad!, start: start, end: end, options: [])

c.restoreGState()

let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

Setup a CGGradient first with the desired colors. Then for a linear gradient you use drawLinearGradient. For a radial gradient, use drawRadialGradient.

like image 157
rmaddy Avatar answered Oct 29 '22 18:10

rmaddy