1

I'm able to use CGContextDrawRadialGradient to make a sphere that does an alpha fade to UIColor.clearColor and it works.

However, I'm trying to do this type of thing:

enter image description here

While placing some strategic spheres around makes for an interesting effect (similar to LED backlights in strategic places), I would love to get a true glow. How can I draw a glow around a rounded rectangle in drawRect?

Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421
  • Would a colored shadow be sufficient? – Ian Henry Apr 09 '12 at 22:10
  • @IanHenry not really because it would end abruptly instead of gradually alpha'ing out. I realize that I could do a few "rings" of varying alpha's, but I'm looking for something less hacky. – Dan Rosenstark Apr 09 '12 at 22:11
  • 1
    The blur of the shadow can be changed in `CGContextSetShadowWithColor`; that allows you to do something very similar to the image you've shown (you don't get precise control over the shadow gradient, though). – Ian Henry Apr 09 '12 at 22:15
  • @IanHenry I will check that out, then. I don't need that much control as long as it looks good ;) On the other hand, if you want to put up an answer with a tiny little example image/code/both, that would be good for SO. – Dan Rosenstark Apr 09 '12 at 22:28

1 Answers1

2

You can create a glow effect around any path using CGContextSetShadowWithColor, but you don't get precise control over the appearance. In particular, the default shadow is fairly light:

the default shadow

And the only way I know of to make it darker is to draw it again over itself:

enter image description here

Not optimal, but it approximates what you want pretty well.

Those images were generated by the following drawRect:

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGMutablePathRef path = CGPathCreateMutable();

    int padding = 20;
    CGPathMoveToPoint(path, NULL, padding, padding);
    CGPathAddLineToPoint(path, NULL, rect.size.width - padding, rect.size.height / 2);
    CGPathAddLineToPoint(path, NULL, padding, rect.size.height - padding);

    CGContextSetShadowWithColor(context, CGSizeZero, 20, UIColor.redColor.CGColor);
    CGContextSetFillColorWithColor(context, UIColor.blueColor.CGColor);

    CGContextAddPath(context, path);
    CGContextFillPath(context);
    // CGContextAddPath(context, path);
    // CGContextFillPath(context);

    CGPathRelease(path);
}

One thing to bear in mind is that rendering fuzzy shadows is fairly expensive, which may or may not be a problem depending on how often your views are redrawn. If the shadows don't need to animate, consider rendering them to a UIImage once and just displaying the result in a UIImageView.

Ian Henry
  • 22,255
  • 4
  • 50
  • 61
  • do you think it's more expensive than 2-color gradients? My guess would be that it'd be similar. – Dan Rosenstark Apr 09 '12 at 22:48
  • 1
    If you're drawing a radial gradient it's probably cheaper than a shadow for an arbitrary path, but if you figured out a way to draw the gradients in the same shape as the shadow then it's probably exactly the same. Only testing will tell! – Ian Henry Apr 09 '12 at 22:52
  • I'll put that in the "to test" bin, which is quite large and rarely gets emptied (unless there's a performance or memory prob). Thanks again – Dan Rosenstark Apr 09 '12 at 22:56
  • Testing revealed performance problems with this type of drawing. However, you don't have to render to a `UIImage`if you can manage to get `drawRect` not to fire, which is generally quite easy. – Dan Rosenstark May 15 '12 at 13:43
  • You might want to look into `CALayer`'s `shouldRasterize` property if the shadow never changes. It can give you great performance improvements with minimal effort, but has its limitations. (If you do use it, make sure you set the `rasterizationScale` to `UIScreen.mainScreen.scale` as well) – Ian Henry May 16 '12 at 03:39
  • It really does change often. The issue is that it doesn't have to. There's almost always an architectural win that makes the user feel just fine, too :) – Dan Rosenstark May 16 '12 at 05:31
  • What's wrong with my shadow? Its not showing at all! CGContextSetShadowWithColor(context, CGSizeZero, 200, UIColor.redColor.CGColor); CGContextSetFillColorWithColor(context, UIColor.blueColor.CGColor); those two lines don't do anything – Van Du Tran Dec 20 '13 at 02:31