UIBezierPath with color gradient UIBezierPath with color gradient objective-c objective-c

UIBezierPath with color gradient


Use CAGradientLayer and mask it using CAShapeLayer Something like this

- (void)addCircle{    CAShapeLayer *shapeLayer = [CAShapeLayer new];    shapeLayer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(CGRectMake(10, 10, 100, 100), 4, 4)].CGPath;    shapeLayer.strokeColor = [UIColor redColor].CGColor;    shapeLayer.contentsScale = [UIScreen mainScreen].scale;    shapeLayer.shouldRasterize = NO;    CAGradientLayer *_gradientLayer = [CAGradientLayer layer];    _gradientLayer.frame =self.view.bounds;    _gradientLayer.startPoint = CGPointMake(0.0, 1);    _gradientLayer.endPoint = CGPointMake(1, 0);    _gradientLayer.colors = @[(id)[UIColor blueColor].CGColor,(id)[UIColor redColor].CGColor];    //Add gradient layer to view    [self.view.layer addSublayer:_gradientLayer];    _gradientLayer.mask = shapeLayer;}

Above method will add a triangle may be you need to change start and end points. Also you can change gradient values to whatever you need.

Apple Docs

CAGradientLayer Tutorial

Update After update its more clear that its not triangle you want, but what you need is possible with CAGradientLayer and CAShapeLayer, you need to follow same approach where you can add gradient with different colors and locations (stops)(if you are adding locations then make sure locations and colors are equal) and then mask it with CAShapeLayer which was circle.


you can give it a try :)

- (void)drawRect:(CGRect)rect{    CGFloat arcStep = (M_PI *2) / 360; // M_PI*2 is equivalent of full cirle    BOOL clocklwise = NO;    CGFloat x = CGRectGetWidth(rect) / 2; // circle's center    CGFloat y = CGRectGetHeight(rect) / 2; // circle's center    CGFloat radius = MIN(x, y) / 2;    CGContextRef ctx = UIGraphicsGetCurrentContext();    // draw colorful circle    CGContextSetLineWidth(ctx, radius*2);    for (CGFloat i = 0; i < 360; i+=1)    {        UIColor* c = [UIColor colorWithHue:i/360 saturation:1. brightness:1. alpha:1];        CGContextSetStrokeColorWithColor(ctx, c.CGColor);        CGFloat startAngle = i * arcStep;        CGFloat endAngle = startAngle + arcStep + 0.02;        CGContextAddArc(ctx, x, y, radius, startAngle, endAngle, clocklwise);        CGContextStrokePath(ctx);    }    // drawing circles then, you might want few of them - smaller radius and less alpha with each step    UIColor* c = [[UIColor whiteColor] colorWithAlphaComponent: 0.03];    for (CGFloat fillRadius = radius/2; fillRadius > 0; fillRadius -= 1.f)    {        CGContextSetLineWidth(ctx, fillRadius*2);        CGContextSetStrokeColorWithColor(ctx, c.CGColor);        CGContextAddArc(ctx, x, y, fillRadius, 0, M_PI * 2, clocklwise);        CGContextStrokePath(ctx);    }}


Another take on Oleg's answer regarding the saturation (white gradient) that I find more pleasing, and in Swift (3).

You can add steps to the gradient if you want a bigger white circle (ex a 2nd white step at 0.2)

import UIKitclass HSView: UIView {    override func draw(_ rect: CGRect) {        let arcStep = 2 * CGFloat.pi / 360        let isClockwise = false        let x = rect.width / 2        let y = rect.height / 2        let radius = min(x, y) / 2        let ctx = UIGraphicsGetCurrentContext()        ctx?.setLineWidth(2 * radius)        for i in 0..<360 {            let color = UIColor(hue: CGFloat(i)/360, saturation: 1, brightness: 1, alpha: 1)            let startAngle = CGFloat(i) * arcStep            let endAngle = startAngle + arcStep + 0.02            ctx?.setStrokeColor(color.cgColor)            ctx?.addArc(center: CGPoint(x: x, y: y), radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: isClockwise)            ctx?.strokePath()        }        let gradient = CGGradient(colorsSpace: UIColor.white.cgColor.colorSpace,                                  colors: [                                    UIColor.white.cgColor,                                    UIColor.white.withAlphaComponent(0).cgColor,                                    ] as CFArray,                                  locations: [                                    0,                                    1,            ]        )        ctx?.drawRadialGradient(gradient!, startCenter: CGPoint(x: x, y: y), startRadius: 0, endCenter: CGPoint(x: x, y: y), endRadius: 2 * radius, options: .drawsAfterEndLocation)    }}

Result