How to add a drop shadow to a UIButton?

IphoneUibutton

Iphone Problem Overview


I would like to add a drop shadow to a UIButton. I tried to use self.layer.shadow* properties. Those properties work in UIView, but they behave differently in UIButton. I would really appreciate it if I could get any pointers to draw the drop shadow. Thank you!

self.layer.cornerRadius = 8.0f;
self.layer.masksToBounds = YES;
self.layer.borderWidth = 1.0f;
	
self.layer.shadowColor = [UIColor greenColor].CGColor;
self.layer.shadowOpacity = 0.8;
self.layer.shadowRadius = 12;
self.layer.shadowOffset = CGSizeMake(12.0f, 12.0f);

Iphone Solutions


Solution 1 - Iphone

There is only one tiny mistake in the question that causes the shadow to not be displayed: masksToBounds:YES also masks the shadow! Here's the correct code:

self.layer.cornerRadius = 8.0f;
self.layer.masksToBounds = NO;
self.layer.borderWidth = 1.0f;

self.layer.shadowColor = [UIColor greenColor].CGColor;
self.layer.shadowOpacity = 0.8;
self.layer.shadowRadius = 12;
self.layer.shadowOffset = CGSizeMake(12.0f, 12.0f);

Unfortunately, this means we cannot mask the content and have a shadow at the same time without tricks.

Remember to #import <QuartzCore/QuartzCore.h>.

Solution 2 - Iphone

Here's a easy solution if you are using a UIButton:

#import <QuartzCore/QuartzCore.h>

button.imageView.layer.cornerRadius = 7.0f;
button.layer.shadowRadius = 3.0f;
button.layer.shadowColor = [UIColor blackColor].CGColor;
button.layer.shadowOffset = CGSizeMake(0.0f, 1.0f);
button.layer.shadowOpacity = 0.5f;
button.layer.masksToBounds = NO;

Just got it working, and figured it was worth posting. Hope that Helps!

Solution 3 - Iphone

Here's a subclass that not only creates the drop shadow, but the button animates down when you press on it.

//
//  ShadowButton.h

#import <Foundation/Foundation.h>

@interface ShadowButton : UIButton {
}

@end

//
//  ShadowButton.m

#import "ShadowButton.h"
#import <QuartzCore/QuartzCore.h>

@implementation ShadowButton

-(void)setupView{
    
    self.layer.shadowColor = [UIColor blackColor].CGColor;
    self.layer.shadowOpacity = 0.5;
    self.layer.shadowRadius = 1;
    self.layer.shadowOffset = CGSizeMake(2.0f, 2.0f);

}

-(id)initWithFrame:(CGRect)frame{
    if((self = [super initWithFrame:frame])){
        [self setupView];
    }
    
    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder{
    if((self = [super initWithCoder:aDecoder])){
        [self setupView];
    }
    
    return self;
}

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    self.contentEdgeInsets = UIEdgeInsetsMake(1.0,1.0,-1.0,-1.0);
    self.layer.shadowOffset = CGSizeMake(1.0f, 1.0f);
    self.layer.shadowOpacity = 0.8;
    
    [super touchesBegan:touches withEvent:event];

}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    self.contentEdgeInsets = UIEdgeInsetsMake(0.0,0.0,0.0,0.0);
    self.layer.shadowOffset = CGSizeMake(2.0f, 2.0f);
    self.layer.shadowOpacity = 0.5;

    [super touchesEnded:touches withEvent:event];
    
}

@end

Solution 4 - Iphone

You can create a subclass and configure its values in Xcode

Below is an example:

import UIKit
import QuartzCore

@IBDesignable
class CustomButton: UIButton {

@IBInspectable var cornerRadius: CGFloat = 0 {
    didSet {
        layer.cornerRadius = cornerRadius
    }
}

@IBInspectable var borderWidth: CGFloat = 0 {
    didSet {
        layer.borderWidth = borderWidth
    }
}

@IBInspectable var borderColor: UIColor = UIColor.gray {
    didSet {
        layer.borderColor = borderColor.cgColor
    }
}

@IBInspectable var shadowColor: UIColor = UIColor.gray {
    didSet {
        layer.shadowColor = shadowColor.cgColor
    }
}

@IBInspectable var shadowOpacity: Float = 1.0 {
    didSet {
        layer.shadowOpacity = shadowOpacity
    }
}

@IBInspectable var shadowRadius: CGFloat = 1.0 {
    didSet {
        layer.shadowRadius = shadowRadius
    }
}

@IBInspectable var masksToBounds: Bool = true {
    didSet {
        layer.masksToBounds = masksToBounds
    }
}

@IBInspectable var shadowOffset: CGSize = CGSize(width: 12, height: 12) {
    didSet {
        layer.shadowOffset = shadowOffset
    }
}


 }

Solution 5 - Iphone

You can subclass UIButton and overwrite the drawRect: method and add manually a drop shadow. That's much more work and you should now a few things about quartz 2d, but the result is exactly what you want. Otherwise you could just add an image, but I prefere to subclass UIButton, because it is very flexible regarding the size of the button, it's more general.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChris FrostView Question on Stackoverflow
Solution 1 - IphonefzwoView Answer on Stackoverflow
Solution 2 - IphonemsgambelView Answer on Stackoverflow
Solution 3 - IphoneavanceView Answer on Stackoverflow
Solution 4 - IphoneAbdul YasinView Answer on Stackoverflow
Solution 5 - IphoneburkiView Answer on Stackoverflow