Is it possible to add a shadow to the text in a UITextField
?

- 12,937
- 5
- 50
- 82

- 5,143
- 5
- 30
- 32
4 Answers
As of 3.2, you can use the CALayer shadow properties.
_textField.layer.shadowOpacity = 1.0;
_textField.layer.shadowRadius = 0.0;
_textField.layer.shadowColor = [UIColor blackColor].CGColor;
_textField.layer.shadowOffset = CGSizeMake(0.0, -1.0);
-
1Works great. On the iPad, you should change the offset to CGSizeMake(0.0, 1.0) and the color to white. – Thomas Feb 06 '11 at 21:17
-
16Indeed, easiest solution. You'll need to `#import
` for this to work. – Guillaume Boudreau Nov 15 '11 at 15:10 -
I used this code to apply the shadow on UILabel's text. Worked perfectly! By using label.layer.shadowOpacity, etc. the text got shadowed – BBog Feb 23 '12 at 14:01
-
Strange Im only able to use the shadowColor and shadowOffset properties on my UILabel. The layer properties have no affect. I've added QuartzCore to my project. – wprater Jun 10 '12 at 22:52
-
@wprater ....you have to import `
` as Guillaume Boudreau previosly stated. It's not enough to import it. You will then be able to use those properties. – George Oct 02 '12 at 07:40
I have a slightly different problem - I want a blurred shadow on a UILabel. Luckily, the solution to this turned out to be number (2) from Tyler
Here's my code :
- (void) drawTextInRect:(CGRect)rect {
CGSize myShadowOffset = CGSizeMake(4, -4);
CGFloat myColorValues[] = {0, 0, 0, .8};
CGContextRef myContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(myContext);
CGColorSpaceRef myColorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef myColor = CGColorCreate(myColorSpace, myColorValues);
CGContextSetShadowWithColor (myContext, myShadowOffset, 5, myColor);
[super drawTextInRect:rect];
CGColorRelease(myColor);
CGColorSpaceRelease(myColorSpace);
CGContextRestoreGState(myContext);
}
This is in a class that extends from UILabel and draws the text with a shadow down and to the right 4px, the shadow is grey at 80% opacity and is sightly blurred.
I think that Tyler's solution number 2 is a little better for performance than Tyler's number 1 - you're only dealing with one UILabel in the view and, assuming that you're not redrawing every frame, it's not a hit in rendering performance over a normal UILabel.
PS This code borrowed heavily from the Quartz 2D documentation

- 23,815
- 10
- 63
- 101

- 38,189
- 13
- 98
- 110
-
Thanks for the code! You can drop the CGContextSetShadow line since you're calling CGContextSetShadowWithColor. According to CGContext.h CGContextSetShadow is "Equivalent to calling CGContextSetShadowWithColor(context, offset, blur, color) where color is black with 1/3 alpha" – johnboiles Jan 27 '11 at 18:51
-
Thanks - I've removed that line - typical cut-and-paste-from-example error :) – deanWombourne Jan 27 '11 at 20:47
-
The "Quartz 2D documentation" link is broken, the new link is: http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_shadows/dq_shadows.html – Vamos Jun 21 '11 at 14:24
-
Thanks for the neat snippet. I've used this in my project and after some tries, I found that with 'shadowOffset' set to (0, 0) and 'blur' set to 2, the text label have exactly the drop shadow I need. – Yuanfei Zhu Feb 19 '12 at 20:48
I don't think you get built-in support for text shadows here, the way you do with UILabel
.
Two ideas:
(1) [Moderately tricky to code.] Add a second UITextField
behind the original, at a very small offset (maybe by (0.2,0.8)? ). You can listen to every text change key-by-key by implementing the textField:shouldChangeCharactersInRange:replacementString:
method in the UITextFieldDelegate
protocol. Using that, you can update the lower text simultaneously. You could also make the lower text (the shadow text) gray, and even slightly blurry using the fact that fractionally-offset text rects appear blurry. Added: Oh yea, don't forget to set the top text field's background color to [UIColor clearColor]
if you go with this idea.
(2) [Even more fun to code.] Subclass UITextField
and override the drawRect:
method. I haven't done this before, so I'll mention up front that this depends on this being the designated drawing method, and it may turn out that you have to override another drawing function, such as drawTextInRect:
, which is specific to UITextField
. Now set up the drawing context to draw shadows via the CGContextSetShadow
functions, and call [super drawRect:rect];
. Hopefully that works -- in case the original UITextField
code clears the drawing context's shadow parameters, that idea is hosed, and you'll have to write the whole drawing code yourself, which I anti-recommend because of all the extras that come with UITextFields
like copy-and-paste and kanji input in Japanese.

- 28,498
- 11
- 90
- 106
-
2You should definitely use the answer below from egarc, much better way to solve this problem! – Mac_Cain13 Sep 03 '12 at 14:14
-
1That's true, @Mac_Cain13. Those CALayer properties were added in iOS 3.2, which wasn't released when I wrote my answer. – Tyler Sep 04 '12 at 03:00
Although the method of applying the shadow directly to the UITextView
will work, it's the wrong way to do this. By adding the shadow directly with a clear background color, all subviews will get the shadow, even the cursor.
The approach that should be used is with NSAttributedString
.
NSMutableAttributedString* attString = [[NSMutableAttributedString alloc] initWithString:textView.text];
NSRange range = NSMakeRange(0, [attString length]);
[attString addAttribute:NSFontAttributeName value:textView.font range:range];
[attString addAttribute:NSForegroundColorAttributeName value:textView.textColor range:range];
NSShadow* shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor whiteColor];
shadow.shadowOffset = CGSizeMake(0.0f, 1.0f);
[attString addAttribute:NSShadowAttributeName value:shadow range:range];
textView.attributedText = attString;
However textView.attributedText is for iOS6. If you must support lower versions, you could use the following approach. (Dont forget to add #import <QuartzCore/QuartzCore.h>
)
CALayer *textLayer = (CALayer *)[textView.layer.sublayers objectAtIndex:0];
textLayer.shadowColor = [UIColor whiteColor].CGColor;
textLayer.shadowOffset = CGSizeMake(0.0f, 1.0f);
textLayer.shadowOpacity = 1.0f;
textLayer.shadowRadius = 0.0f;

- 7,342
- 8
- 68
- 104
-
3Diamond in the rough answer. This is SO much faster than setting the CALayer shadow properties. – user Jun 23 '14 at 06:41
-
2This also works for adding the blur to the shadow if you add `shadow.shadowBlurRadius = 6.f;` – gavdotnet Jun 05 '15 at 01:30