48

Actually I love UILabel. They're sweet. Now I had to go to UITextView because UILabel is not aligning text vertically to the top. Damn. One thing I really need is a text shadow. UILabel has it. UITextView seems to not have it. But I guess that guy just uses the same underlying UIKit NSString additions?? Maybe someone already has a solution for that problem? What would I overwrite?

Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
dontWatchMyProfile
  • 45,440
  • 50
  • 177
  • 260
  • 2
    i think you should accept adjwilli answer, because it's easy ant i think the most will agree that it's the right way to do it. – Lukas Nov 14 '12 at 07:29

7 Answers7

156
text.layer.shadowColor = [[UIColor whiteColor] CGColor];
text.layer.shadowOffset = CGSizeMake(1.0f, 1.0f);
text.layer.shadowOpacity = 1.0f;
text.layer.shadowRadius = 1.0f;

And don't forget to add up top:

#import <QuartzCore/QuartzCore.h>
adjwilli
  • 9,658
  • 4
  • 35
  • 29
  • 1
    The answer marked correct will work I suppose but its messy and generally poor form. – averydev May 10 '11 at 02:19
  • 2
    I wish I could mark this up further -- this is the appropriate way to add a shadow to a UITextView. The other method is very heavy handed and not at all the way that should be done for anything other than very trivial uses of UITextView. – Dennis Munsie May 26 '11 at 03:40
  • weird behaviour: this approach adds shadow to the text itself, not to the uitextview box. I would like to add shadow to the box not to the text. – Alex Tau Jun 08 '11 at 08:35
  • 2
    This works perfectly, kindly mark this as an alternative answer :) – Bani Uppal Jun 17 '12 at 20:28
  • text.layer.masksToBounds = NO; is needed also – Nikita Oct 07 '13 at 11:59
  • 1
    Just used the exact code in adjwilli's answer and it worked perfectly without any need for anything else. THANK YOU, man. – Cyprus106 Apr 27 '14 at 21:06
  • 1
    textView's background needs to be set as clearColor in order for this to work – Lucas Aug 07 '15 at 17:21
16

The answer with

text.layer.shadowColor

adds shadow to whole textView, perhaps it works, but it adds shadow not only to text.

The correct answer is:

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 = 1.0f;
Nikita
  • 1,811
  • 1
  • 20
  • 41
13

Swift 3


let textView = UITextView(frame: view.frame)
textView.font = UIFont(name: "Helvetica", size: 64.0)
textView.textColor = .red
textView.text = "Hello World"

textView.layer.shadowColor = UIColor.black.cgColor
textView.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)
textView.layer.shadowOpacity = 1.0
textView.layer.shadowRadius = 2.0
textView.layer.backgroundColor = UIColor.clear.cgColor

Swift 2.3


let textView = UITextView(frame: view.frame)
textView.font = UIFont(name: "Helvetica", size: 64.0)
textView.textColor = UIColor.redColor()
textView.text = "Hello World"    

textView.layer.shadowColor = UIColor.blackColor().CGColor
textView.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)
textView.layer.shadowOpacity = 1.0
textView.layer.shadowRadius = 2.0
textView.layer.backgroundColor = UIColor.clearColor().CGColor
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
12

enter image description here

This Swift example uses the attributed string method of adding shadow to text. See this answer for more about attributed strings in Swift. This method (as opposed to using the layer method) gives you the flexibility to set the shadow on a range of text if you want to.

// Create a string
let myString = "Shadow"

// Create a shadow
let myShadow = NSShadow()
myShadow.shadowBlurRadius = 3
myShadow.shadowOffset = CGSize(width: 3, height: 3)
myShadow.shadowColor = UIColor.gray

// Create an attribute from the shadow
let myAttribute = [ NSAttributedStringKey.shadow: myShadow ]

// Add the attribute to the string
let myAttrString = NSAttributedString(string: myString, attributes: myAttribute)

// set the attributed text on a label
myLabel.attributedText = myAttrString // can also use with UITextView

Updated for Swift 4

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
9

In iOS 6+ use attributed text

NSShadow * shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor blackColor];
shadow.shadowOffset = CGSizeMake(2, 2);

NSDictionary * textAttributes =
@{ NSForegroundColorAttributeName : [UIColor blueColor],
   NSShadowAttributeName          : shadow,
   NSFontAttributeName            : [UIFont boldSystemFontOfSize:20] };

textView.attributedText = [[NSAttributedString alloc] initWithString:@"Hello" 
                                                          attributes:textAttributes];

Hello example

Robert
  • 37,670
  • 37
  • 171
  • 213
0

It depends on the version of iOS you are using. Beginning with iOS 6 there is a single shadow supported, you set that as an attribute on an NSAttributedString that you then set onthe label.

Cocoanetics
  • 8,171
  • 2
  • 30
  • 57
-1

swift 4, swift 4.2, swift 5 and above Simple and elegant solution , can use from interface builder easily

extension UIView {
    /* The color of the shadow. Defaults to opaque black. Colors created
     * from patterns are currently NOT supported. Animatable. */
    @IBInspectable var shadowColor: UIColor? {
        set {
            layer.shadowColor = newValue!.cgColor
        }
        get {
            if let color = layer.shadowColor {
                return UIColor(cgColor: color)
            }
            else {
                return nil
            }
        }
    }

    /* The opacity of the shadow. Defaults to 0.4 Specifying a value outside the
     * [0,1] range will give undefined results. Animatable. */
    @IBInspectable var shadowOpacity: Float {
        set {
            layer.shadowOpacity = newValue
        }
        get {
            return layer.shadowOpacity
        }
    }

    /* The shadow offset. Defaults to (1, 2). Animatable. */
    @IBInspectable var shadowOffset: CGPoint {
        set {
            layer.shadowOffset = CGSize(width: newValue.x, height: newValue.y)
        }
        get {
            return CGPoint(x: layer.shadowOffset.width, y:layer.shadowOffset.height)
        }
    }

    /* The blur radius used to create the shadow. Defaults to 3. Animatable. */
    @IBInspectable var shadowRadius: CGFloat {
        set {
            layer.shadowRadius = newValue
        }
        get {
            return layer.shadowRadius
        }
    }
}
midhun p
  • 1,987
  • 18
  • 24