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 wo
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.
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>
.
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!
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
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
}
}
}