Is it possible to draw with simple text shadows when using the NSString UIKit additions? I mean without writing code to draw twice in two colors, as can be done with various
A couple of thoughts:
The UITextAttributeTextShadow...
keys are intended for when using a text attribute dictionary with, for example, UIAppearance
methods:
NSDictionary *attributes = @{UITextAttributeTextShadowColor : [UIColor blackColor],
UITextAttributeTextShadowOffset : [NSValue valueWithUIOffset:UIOffsetMake(2.0, 0.0)],
UITextAttributeTextColor : [UIColor yellowColor]};
[[UINavigationBar appearance] setTitleTextAttributes:attributes];
The UITextAttributeTextShadow...
keys are designed for use only in those methods that accept a text attributes dictionary.
The closest equivalent key when drawing text strings is the use of attributed strings with the NSShadowAttributeName
key:
- (void)drawRect:(CGRect)rect
{
UIFont *font = [UIFont systemFontOfSize:50];
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor blackColor];
shadow.shadowBlurRadius = 0.0;
shadow.shadowOffset = CGSizeMake(0.0, 2.0);
NSDictionary *attributes = @{NSShadowAttributeName : shadow,
NSForegroundColorAttributeName : [UIColor yellowColor],
NSFontAttributeName : font};
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:@"this has shadows" attributes:attributes];
[attributedText drawInRect:rect];
}
If you're concerned about the performance hit of a shadow algorithm capable of doing a bezier curve shadow, though, NSShadow
may suffer from that. But doing some benchmarks, changing the shadowBlurRadius
dramatically affects performance. For example, animating the rotation of a complex multi-line text with a shadowBlurRadius
of 10.0
on a slow iPhone 3GS achieved a frame rate of 31 fps, but changing shadowBlurRadius
to 0.0
yielded a frame rate of 60 fps.
Bottom line, using a shadow blur radius of 0.0
eliminates most (if not all) of the computational overhead of a bezier generated shadow.
FYI, I experience a similar performance improvement by setting the blur
value to 0.0
for CGContextSetShadow
, just like I experienced with the attributed text rendition above.
Bottom line, I don't think you should fear the computational overhead of bezier-based shadows as long as you use a blur radius of 0.0
. I wouldn't be surprised if writing the text twice yourself, once for the shadow and again for the foreground color, might even be a bit more efficient, but I'm not sure if the difference will be observable. But I don't know of any API call that will do that for you (other than CGContextSetShadow
with blur
of 0.0
).