I have a UIImageView that I want to add a shadow behind. I wish that apple had that as a property but they have to make lots of things hard for us programmers so I need to ask this question.
-
1Likely, you want to use Core Graphics drawing functions to draw the shadow. – Grant Paul Jan 11 '10 at 19:57
-
These questions are very similar to yours: http://stackoverflow.com/questions/962827/uiimage-shadow, http://stackoverflow.com/questions/1943087/i-am-trying-to-add-a-drop-shadow-to-a-uimageview – Brad Larson Jan 12 '10 at 14:03
5 Answers
There's a better and easier way to do this. UIImageView inherits from UIView so it has a layer property. You can access the layer's shadow properties and bam, you got a shadow.
If you have the UIImageView as an IBOutlet to a nib file, you can just implement the awakeFromNib e.g.
Objective-C
- (void)awakeFromNib {
imageView.layer.shadowColor = [UIColor purpleColor].CGColor;
imageView.layer.shadowOffset = CGSizeMake(0, 1);
imageView.layer.shadowOpacity = 1;
imageView.layer.shadowRadius = 1.0;
imageView.clipsToBounds = NO;
}
Don't forget to #import "QuartzCore/CALayer.h"
For Swift, you can go about it multiple ways. Create a class extension, subclass, or an imageView instance. Whichever the way, the process is the same in modifying the layers shadow property.
Swift 3
override func awakeFromNib() {
super.awakeFromNib()
imageView.layer.shadowColor = UIColor.purple.cgColor
imageView.layer.shadowOffset = CGSize(width: 0, height: 1)
imageView.layer.shadowOpacity = 1
imageView.layer.shadowRadius = 1.0
imageView.clipsToBounds = false
}

- 2,820
- 1
- 19
- 14
-
33You also may need `imageView.clipsToBounds = NO;` or the shadow will be clipped away. – mxcl Nov 01 '10 at 18:31
-
18
-
1@MaxHowell using clipsToBounds added the shadow, but now my image overflow's its bounds as well when using mode "Aspect Fill". Is there a way to clip the image but not the shadow? – Derek Dahmer Nov 18 '11 at 00:33
-
6@DerekDahmer you will have to add the imageView as a subview of another view that you then apply the shadow, and then clip the imageView but not the container view. I have found no other way to handle this sort of thing. – mxcl Nov 18 '11 at 11:24
-
5
-
1Wow, rasterization helps a lot if you animate your imageView. If you use it, you should also add this: `imageView.layer.rasterizationScale = image.scale;` to be compatible with retina images. – secondcitysaint Sep 27 '12 at 15:04
The simplest thing to do is add a shadow layer to your image view:
CALayer *layer = [CALayer layer];
CGRect bounds = self.bounds;
layer.bounds = bounds;
layer.position = CGPointMake(bounds.size.width / 2 + 3, bounds.size.height / 2 + 3);
layer.backgroundColor = [UIColor colorWithWhite: 0.25 alpha: 0.55].CGColor;
layer.zPosition = -5;
[self.layer addSublayer: layer];
Be sure "Clip Subviews" is turned off for the view

- 85,404
- 22
- 176
- 172
-
1why are you making a CGRect *bounds when you can just set the layer's bounds to self.bounds? And where does the shadow come into place? – Jab Jan 11 '10 at 20:04
-
I create a temp variable for readability; typing out self.bounds is a little longer than just bounds, and makes the code a little less readable. This layer IS the shadow. Of course, this presupposes you've got a square image; if you're doing a non-rectangular image, you'll have to use a custom image mask. – Ben Gottlieb Jan 11 '10 at 20:27
-
Well I want to have it faded and I don't know how I would do that. Pleas help! – Jab Jan 12 '10 at 02:07
-
1Fading is a separate task entirely. If you want to have a custom shadow (something other than a simple dark rectangle behind your image), you should take the image, make it into a mask (ie, all black and transparent), apply your fade, and then draw it behind the original, using either Quartz, or sticking into a layer. – Ben Gottlieb Jan 12 '10 at 03:33
Swift solution with extension. Subclassing is not required. Call myImage.addShadow()
from viewDidLoad()
. This should work for UIView
and UIImageView
.
extension UIView {
func addShadow() {
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 0)
layer.shadowOpacity = 0.5
layer.shadowRadius = 5
clipsToBounds = false
}
}

- 4,387
- 2
- 32
- 50
-
When I try to call this I get 'Value of type 'UIImage' has no member 'addShadow' – user1904273 Jan 28 '19 at 19:40
in additional to that, if you want to make white border and shadow you can use that code :
//shadow part
imageView.layer.shadowColor = [UIColor blackColor].CGColor;
imageView.layer.shadowOffset = CGSizeMake(0, 1);
imageView.layer.shadowOpacity = 1;
imageView.layer.shadowRadius = 1.0;
//white border part
[imageView.layer setBorderColor: [[UIColor whiteColor] CGColor]];
[imageView.layer setBorderWidth: 2.0];

- 211
- 3
- 9
-
But in this case, how do you make the shadow part of the .image property, to let's say, save or show that image somewhere else? – alejandrormz Nov 14 '14 at 17:09
-
You can't. You aren't editing the image, you are adorning it for display. To actually edit the bitmap data is *much* more complicated. Consider simply adorning the image everywhere you display it as you generally do not want to process images to add these sort of effects unless you do so in a back end that processes them in batches. – Tim Dec 30 '15 at 16:16
Swift 5.x
profileImageView.layer.cornerRadius = profileImageView.frame.size.width/2
profileImageView.clipsToBounds = false
profileImageView.layer.shadowColor = UIColor.black.cgColor
profileImageView.layer.shadowOpacity = 0.7
profileImageView.layer.shadowOffset = CGSize(width: 2, height: 2)
profileImageView.layer.shadowRadius = 10

- 34,887
- 11
- 106
- 133