Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applying a Gradient to CAShapeLayer

Does anyone have any experience in applying a Gradient to a CAShapeLayer? CAShapeLayer is a fantastic layer class, but it appears to only support solid fill coloring, whereas I'd like it to have a gradient fill (actually an animatable gradient at that).

Everything else to do with CAShapeLayer (shadows, shapes, stroke color, animatable shape path) is fantastic.

I've tried placing a CAGradientLayer inside a CAShapeLayer, or indeed setting the CAShapeLayer as the mask of the GradientLayer and adding both to a container layer, but these don't have the right outcome.

Should I subclass CAShapeLayer, or is there a better way forward?

Thanks.

like image 382
user366126 Avatar asked Jan 19 '11 10:01

user366126


1 Answers

You could use the path of your shape to create a masking layer and apply that on the gradient layer, like this:

UIView *v = [[UIView alloc] initWithFrame:self.window.frame];  CAShapeLayer *gradientMask = [CAShapeLayer layer];    gradientMask.fillColor = [[UIColor clearColor] CGColor]; gradientMask.strokeColor = [[UIColor blackColor] CGColor]; gradientMask.lineWidth = 4; gradientMask.frame = CGRectMake(0, 0, v.bounds.size.width, v.bounds.size.height);  CGMutablePathRef t = CGPathCreateMutable();     CGPathMoveToPoint(t, NULL, 0, 0); CGPathAddLineToPoint(t, NULL, v.bounds.size.width, v.bounds.size.height);  gradientMask.path = t;   CAGradientLayer *gradientLayer = [CAGradientLayer layer]; gradientLayer.startPoint = CGPointMake(0.5,1.0); gradientLayer.endPoint = CGPointMake(0.5,0.0); gradientLayer.frame = CGRectMake(0, 0, v.bounds.size.width, v.bounds.size.height); NSMutableArray *colors = [NSMutableArray array]; for (int i = 0; i < 10; i++) {     [colors addObject:(id)[[UIColor colorWithHue:(0.1 * i) saturation:1 brightness:.8 alpha:1] CGColor]]; } gradientLayer.colors = colors;  [gradientLayer setMask:gradientMask]; [v.layer addSublayer:gradientLayer]; 

If you want to also use the shadows, you would have to place a "duplicate" of the shape layer under the gradient layer, recycling the same path reference.

like image 184
Palimondo Avatar answered Oct 05 '22 08:10

Palimondo