On a CAShapeLayer
, I've drawn a closed UIBezierPath
. I can fill this shape by setting the fillColor
, however I want to fill the shape with a gradient. How can I set up the CAGradientLayer
so it clips to the shape outlined by the bezier path?
Asked
Active
Viewed 1.1k times
8

Thorsten
- 12,921
- 17
- 60
- 79
2 Answers
20
A draft example would be the following:
...
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor *gradientColor = [UIColor colorWithRed:0.51 green:0.0 blue:0.49 alpha:1.0];
NSArray *gradientColors = [NSArray arrayWithObjects:
(id)[UIColor blueColor].CGColor,
(id)gradientColor.CGColor,
(id)[UIColor redColor].CGColor, nil];
CGFloat gradientLocations[] = {0, 0.5, 1};
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)gradientColors, gradientLocations);
UIBezierPath *roundedRectanglePath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(10, 10, 200, 200) cornerRadius:6];
CGContextSaveGState(context);
[roundedRectanglePath fill];
[roundedRectanglePath addClip];
CGContextDrawLinearGradient(context, gradient, CGPointMake(10, 10), CGPointMake(210, 10), 0);
CGColorSpaceRelease(colorSpace);
CGGradientRelease(gradient);
...

simonbs
- 7,932
- 13
- 69
- 115

WhiteTiger
- 1,691
- 1
- 18
- 23
-
This is nice, but you should also release the gradient and color space. – Sulthan Mar 17 '13 at 13:48
-
since the original post featured a Mask, I also added the following: `CGContextAddPath(context, roundedRectanglePath.CGPath);` `CGContextClip(context);` before `CGContextDrawLinearGradient` – maggix Jul 04 '13 at 10:32
6
What you want is a mask. CAGradientlayer has a -setMask method that can clip it to the bounds of your shape like so:
[gradientLayer setMask:shapeLayer];

CodaFi
- 43,043
- 8
- 107
- 153