iPhone UILabel text soft shadow
Asked Answered
P

15

60

I know soft shadows are not supported by the UILabel out of the box, on the iPhone. So what would be the best way to implement my own one?

EDIT:

Obviously I will subclass the UILabel and draw in the -drawRect: My question is, how do I get the contents of the label as graphics and draw around them, blur them etc...

EDIT 2:

I returned to this question about a year later. In the meantime I've built a class that allows you to easily add soft shadow to a label and tweak it's radius etc and also to draw gradients on the text itself. You can find it on GitHub: https://github.com/doukasd/iOS-Components/tree/master/Views

Pittance answered 10/11, 2009 at 16:13 Comment(1)
how to implement this is Base SDK4.0 ?Eggnog
C
19

This answer to this similar question provides code for drawing a blurred shadow behind a UILabel. The author uses CGContextSetShadow() to generate the shadow for the drawn text.

Carpal answered 10/11, 2009 at 18:19 Comment(6)
That's great and it works as advertised! Thanks. But do you have an idea how I can make that shadow more intense? Since it part of the context, I can't draw it more than once, which would do the trick.Pittance
You could change the color to be black with a 100% opacity (in his example, it's only 80%), as well as change the shadow radius within the CGContextSetShadow() call. You might also try shifting the offset from the 4,-4 position that he's set.Carpal
Yes I have tried 100% opacity etc. And regarding the size, the larger you set it to be, the less visible the shadow is... I am looking for something similar to the Shadow Effect in Flash, which you can set to more than 100%.Pittance
how to implement this is Base SDK4.0 ?Eggnog
@Apple - What's wrong with the code there? Everything in the linked answer still works today on current iOS versions.Carpal
it is not working properly in IOS 4.0 color gradient is show error because its shows there is 0 object in color array but same code is working properly in IOS above 4.3Eggnog
G
191

As of 3.2 there is direct support for shadows in the SDK.

label.layer.shadowColor = [label.textColor CGColor];
label.layer.shadowOffset = CGSizeMake(0.0, 0.0);

#import <QuartzCore/QuartzCore.h> and play with some parameters:

label.layer.shadowRadius = 3.0;
label.layer.shadowOpacity = 0.5;

And, if you find your shadow clipped by the label bounds:

label.layer.masksToBounds = NO;

finally set

label.layer.shouldRasterize = YES;
Gabie answered 20/1, 2011 at 14:29 Comment(10)
Note that to use shadowRadius you have to include the QuartzCore headers: #import <QuartzCore/QuartzCore.h>Eisenstein
For some reason this has no effect on my UILabelVoluptuary
+ 1 for the maskToBounds extra info.Rhythmics
maskToBounds is by default NO, and please edit your example because shadowRadius = 20 is VERY high, so might seen not working (like my case and maybe also for @Pascalius). even 3 (the default) is a bit too much for small labels.Cure
ty, updating w/ your suggestionsGabie
The shadow is so soft that is sometimes difficult to notice :(Guidepost
Also - I have found that you need to set the background color of the label to clearColor, or you will not see the shadow.Rossierossing
May want to add that you can do the same with the User Defined Runtime Attributes in IB.Anaximander
What will happen if you set shouldRasterize to false?Symbology
If you plan on using shouldRasterize, then make sure you also set the rasterizationScale : label.layer.rasterizationScale = [UIScreen mainScreen].scale; Or it may look weird on retina screens.Birddog
T
38

I advise you to use the shadowColor and shadowOffset properties of UILabel:

UILabel* label = [[UILabel alloc] init];
label.shadowColor = [UIColor whiteColor];
label.shadowOffset = CGSizeMake(0,1);
Tacitus answered 2/3, 2010 at 13:15 Comment(3)
Thank you but yes. I was actually looking for soft shadow.Pittance
For "soft" shadow - maybe you can change color properly? for example, i needed "soft" dark shadow. - as blackColor was too sharp, i ended up with grayColor :) Happy coding! :)Beggar
He means a blurry shadow, without sharp edges.Sordino
C
19

This answer to this similar question provides code for drawing a blurred shadow behind a UILabel. The author uses CGContextSetShadow() to generate the shadow for the drawn text.

Carpal answered 10/11, 2009 at 18:19 Comment(6)
That's great and it works as advertised! Thanks. But do you have an idea how I can make that shadow more intense? Since it part of the context, I can't draw it more than once, which would do the trick.Pittance
You could change the color to be black with a 100% opacity (in his example, it's only 80%), as well as change the shadow radius within the CGContextSetShadow() call. You might also try shifting the offset from the 4,-4 position that he's set.Carpal
Yes I have tried 100% opacity etc. And regarding the size, the larger you set it to be, the less visible the shadow is... I am looking for something similar to the Shadow Effect in Flash, which you can set to more than 100%.Pittance
how to implement this is Base SDK4.0 ?Eggnog
@Apple - What's wrong with the code there? Everything in the linked answer still works today on current iOS versions.Carpal
it is not working properly in IOS 4.0 color gradient is show error because its shows there is 0 object in color array but same code is working properly in IOS above 4.3Eggnog
T
17

Additionally to IIDan's answer: For some purposes it is necessary to set

label.layer.shouldRasterize = YES

I think this is due to the blend mode that is used to render the shadow. For example I had a dark background and white text on it and wanted to "highlight" the text using a black shadowy glow. It wasn't working until I set this property.

Theola answered 20/3, 2013 at 16:31 Comment(2)
This is required to make it faster even with dozens of UILabels in view. Without it, shadows are slow if used with opacity.Gunderson
If you plan on using shouldRasterize, then make sure you also set the rasterizationScale : label.layer.rasterizationScale = [UIScreen mainScreen].scale; Or it may look weird on retina screens.Birddog
F
7

Apply the (soft) shadow on the view's layer, like this:

UILabel *label = [[UIabel alloc] init];
label.layer.shadowColor = [[UIColor whiteColor] CGColor];
label.layer.shadowOpacity = 1.0;
Friarbird answered 19/5, 2010 at 9:45 Comment(0)
S
7

To keep things up to date: Creating the shadow in Swift is as easy as that:

Import the QuartzCore Framework

import QuartzCore

And set the shadow attributes to your label

titleLabel.shadowColor = UIColor.blackColor()
titleLabel.shadowOffset = CGSizeMake(0.0, 0.0)
titleLabel.layer.shadowRadius = 5.0
titleLabel.layer.shadowOpacity = 0.8
titleLabel.layer.masksToBounds = false
titleLabel.layer.shouldRasterize = true
Selfdeprecating answered 19/8, 2015 at 11:14 Comment(1)
Weirdly, that results in a shadow above (in the y direction) the text instead of aligned with it.Strain
A
5
_nameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_nameLabel.font = [UIFont boldSystemFontOfSize:19.0f];
_nameLabel.textColor = [UIColor whiteColor];
_nameLabel.backgroundColor = [UIColor clearColor];
_nameLabel.shadowColor = [UIColor colorWithWhite:0 alpha:0.2];
_nameLabel.shadowOffset = CGSizeMake(0, 1);

i think you should use the [UIColor colorWithWhite:0 alpha:0.2] to set the alpha value.

Astatic answered 22/7, 2013 at 3:17 Comment(0)
E
4

I tried almost all of these techniques (except FXLabel) and couldn't get any of them to work with iOS 7. I did eventually find THLabel which is working perfectly for me. I used THLabel in Interface Builder and setup User Defined Runtime Attributes so that it's easy for a non programmer to control the look and feel.

https://github.com/MuscleRumble/THLabel

Eschatology answered 22/11, 2013 at 16:3 Comment(0)
A
4

This like a trick,

UILabel *customLabel = [[UILabel alloc] init];

UIColor *color = [UIColor blueColor];
customLabel.layer.shadowColor = [color CGColor];
customLabel.layer.shadowRadius = 5.0f;
customLabel.layer.shadowOpacity = 1;
customLabel.layer.shadowOffset = CGSizeZero;
customLabel.layer.masksToBounds = NO;
Absorbance answered 9/1, 2015 at 7:39 Comment(0)
V
3

Subclass UILabel, as stated, then, in drawRect:, do [self drawTextInRect:rect]; to get the text drawn into the current context. Once it is in there, you can start working with it by adding filters and whatnot. If you want to make a drop shadow with what you just drew into the context, you should be able to use:

CGContextSetShadowWithColor()

Look that function up in the docs to learn how to use it.

Vasta answered 10/11, 2009 at 18:20 Comment(0)
S
3

I wrote a library that provides a UILabel subclass with soft shadow support and a bunch of other effects:

https://github.com/nicklockwood/FXLabel

Sordino answered 7/6, 2012 at 9:20 Comment(0)
S
3

In Swift 3, you can create an extension:

import UIKit

extension UILabel {
    func shadow() {
        self.layer.shadowColor = self.textColor.cgColor
        self.layer.shadowOffset = CGSize.zero
        self.layer.shadowRadius = 3.0
        self.layer.shadowOpacity = 0.5
        self.layer.masksToBounds = false
        self.layer.shouldRasterize = true
    }
}

and use it via:

label.shadow()
Slavin answered 5/1, 2017 at 8:0 Comment(0)
L
1

As of iOS 5 Apple provides a private api method to create labels with soft shadows. The labels are very fast: I'm using dozens at the same time in a series of transparent views and there is no slowdown in scrolling animation.

This is only useful for non-App Store apps (obviously) and you need the header file.

$SBBulletinBlurredShadowLabel = NSClassFromString("SBBulletinBlurredShadowLabel");

CGRect frame = CGRectZero;

SBBulletinBlurredShadowLabel *label = [[[$SBBulletinBlurredShadowLabel alloc] initWithFrame:frame] autorelease];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
label.font = [UIFont boldSystemFontOfSize:12];
label.text = @"I am a label with a soft shadow!";
[label sizeToFit];
Lui answered 5/10, 2011 at 22:43 Comment(3)
You don't want to use this if your app is going to the app store.Invisible
Well, to be fair, he stated that in the answer.Staging
Why wouldn't you want to use this with a potential App Store submission ??Bobolink
F
0

While it's impossible to set a blur radius directly on UILabel, you definitely could change it by manipulating CALayer.

Just set:

//Required properties
customLabel.layer.shadowRadius = 5.0 //set shadow radius to your desired value.
customLabel.layer.shadowOpacity = 1.0 //Choose an opacity. Make sure it's visible (default is 0.0)

//Other options
customLabel.layer.shadowOffset = CGSize(width: 10, height: 10)
customLabel.layer.shadowColor = UIColor.black.cgColor
customLabel.layer.masksToBounds = false

What I hope will help someone and other answers failed to clarify is that it will not work if you also set UILabel Shadow Color property directly on Interface Builder while trying to setup .layer.shadowRadius.

So if setting label.layer.shadowRadius didn't work, please verify Shadow Color for this UILabel on Interface Builder. It should be set to default. And then, please, if you want a shadow color other than black, set this color also through .layer property.

enter image description here

Fryd answered 16/6, 2020 at 20:52 Comment(0)
F
-3

Subclass UILabel, and override -drawInRect:

Falbala answered 10/11, 2009 at 16:15 Comment(1)
Okay that's the obvious part. Then what?Pittance

© 2022 - 2024 — McMap. All rights reserved.