Cokile Ceoi
Cokile Ceoi

Reputation: 1346

CAGradientLayer not draw the gradient correctly

I use CAShapeLayer to draw a circle and set it as the mask of CAGradientLayer, here is the code:

CAShapeLayer *circleShapeLayer = [CAShapelayer new];
// draw circle path code here...

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.colors = @[(__bridge id)[UIColor whiteColor].CGColor,
                         (__bridge id)[UIColor clearColor].CGColor];
// self here means a UIView
gradientLayer.mask = circleShapeLayer;
gradientLayer.frame = self.bounds;
[self.layer addSublayer:gradientLayer];

When I run the app, it will display a gradient circle, but the gradient is strange.

What I want is a circle that at start point, the color is white and at end point the color is clear color, it should look like this:

enter image description here

But the color of the circle in the Simulator screen is:

enter image description here

The color is symmetric.

I think the problem is that I do not set the gradientLayer.colors correctly, how can I fix it?

Upvotes: 0

Views: 759

Answers (3)

ZGski
ZGski

Reputation: 2538

@J.Hunter's answer is correct in that CAGradientLayers cannot draw along an arc. This means that your drawn gradients will be limited to radial and linear. You are specifically looking to create an angled gradient, which I've attempted to do in the past as well.

Unfortunately, CAGradientLayer is bound to these limitations, and the best way I've found to create a masked angled gradient is to mask with a UIImage that contains an angled gradient. This won't be nearly as dynamic as drawing your own gradient, but it seems to be the best (possibly only) option at the moment.

Upvotes: 0

J.Hunter
J.Hunter

Reputation: 586

CAGradientLayer can not paint gradient along an arc. on the other hand, the mask layer's frame is too small than gradient layer's frame to see clear color

Upvotes: 1

emotality
emotality

Reputation: 13035

To Umair's response, it didn't make sense to me at first because even whiteColor or blackColor is being fetched by colorWithRed:green:blue:alpha but then I read this in the documentation:

When rendered, the colors are mapped to the output color space before being interpolated.

So maybe this is really it:

gradientLayer.colors = @[(__bridge id)[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:1.0f].CGColor,
                         (__bridge id)[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:0.0f].CGColor];

Upvotes: 0

Related Questions