Circular CAGradientLayer Mask

2019-07-22 19:26发布

I have a UIView that programmatically draws a "sunburst" pattern using UIBezierPath. Now I would like to extend this by masking the edges with a gradient -- effectively making each "burst" fade from opaque to transparent. I'm think this could be done with a CAGradientLayer mask but I'm not sure how to make it circular.

This is what I'm trying -- it masks the view but the gradient is linear:

    CAGradientLayer *l = [CAGradientLayer layer];
    l.frame = CGRectMake(0.0f, 0.0f, rect.size.width, rect.size.height);
    l.cornerRadius = rect.size.width/2.0f;
    l.masksToBounds = YES;
    l.colors = [NSArray arrayWithObjects:(id)[UIColor blackColor].CGColor, (id)[UIColor clearColor].CGColor, nil];
    self.layer.mask = l;

I'm open to not using CAGradientLayer if anyone knows any other ways to mask a view with a circle with blurred edges.

SOLUTION Thanks to matt's insight, I ended up drawing a mask view using CGContextDrawRadialGradient, rendering that as a UIImage, and using that as a mask layer. If anyone is interested in this process, it is being used in this test project.

3条回答
Ridiculous、
2楼-- · 2019-07-22 20:19

An obvious approach is to draw this effect manually. Start very small and draw the sunburst larger and larger and (at the same time) less and less opaque.

On the other hand, it might be sufficient to make a radial gradient and use it as a mask (vignette effect). Core Graphics will draw the radial gradient for you:

https://developer.apple.com/library/ios/#documentation/graphicsimaging/reference/CGContext/Reference/reference.html#//apple_ref/c/func/CGContextDrawRadialGradient

I'm also very fond of CIFilters for adding touches like this: you should look through the catalogue and see what strikes your fancy:

https://developer.apple.com/library/ios/#documentation/graphicsimaging/reference/CoreImageFilterReference/Reference/reference.html

CIFilter actually gives you a sunburst transition that might suit your purposes, especially if combined with masking and compositing; here's a discussion of the sunburst (used in an animation), from my book:

http://www.apeth.com/iOSBook/ch17.html#_cifilter_transitions

查看更多
叛逆
3楼-- · 2019-07-22 20:27

CAGradientLayer draws linear gradients.

You could try to set a shadow and see if that suits your needs:

l.shadowColor = [UIColor blackColor];
l.shadowRadius = rect.size.width / 2;
查看更多
虎瘦雄心在
4楼-- · 2019-07-22 20:31

You can do this by creating a CALayer instance and give it a delegate that implements drawLayer:inContext: and draws a radial gradient in the implementation of that method. Then use that CALayer as your mask.

查看更多
登录 后发表回答