UIButton bottom shadow
IosObjective CUibuttonIos Problem Overview
I have a UIButton
which is very similar to the standard iOS keyboard alphabet button.
I am not sure how to create a shadow only for the bottom layer like how iOS have done.
I use the below code, but I see a shadow on all the side, not just the bottom:
CALayer *buttonLayer = [[CALayer alloc] init];
buttonLayer.shadowColor = [UIColor grayColor].CGColor;
buttonLayer.shadowOffset = CGSizeMake(0.f,1.f);
buttonLayer.masksToBounds = NO;
buttonLayer.shadowOpacity = 1.f;
Can you please tell me how to achieve the same effect. Thanks in advance.
Ios Solutions
Solution 1 - Ios
You can mix the cornerRadius and shadow properties. I tested it on iOS 8.
Objective-C:
[self.globeButton setImage:[UIImage imageNamed:@"Globe"] forState:UIControlStateNormal];
self.globeButton.backgroundColor = [UIColor colorWithRed:171 green:178 blue:186 alpha:1.0f];
// Shadow and Radius
self.globeButton.layer.shadowColor = [[UIColor colorWithRed:0 green:0 blue:0 alpha:0.25f] CGColor];
self.globeButton.layer.shadowOffset = CGSizeMake(0, 2.0f);
self.globeButton.layer.shadowOpacity = 1.0f;
self.globeButton.layer.shadowRadius = 0.0f;
self.globeButton.layer.masksToBounds = NO;
self.globeButton.layer.cornerRadius = 4.0f;
Swift:
globeButton.setImage(UIImage(named: "Globe"), for: .normal)
globeButton.backgroundColor = UIColor(red: 171/255, green: 178/255, blue: 186/255, alpha: 1.0)
// Shadow Color and Radius
globeButton.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
globeButton.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
globeButton.layer.shadowOpacity = 1.0
globeButton.layer.shadowRadius = 0.0
globeButton.layer.masksToBounds = false
globeButton.layer.cornerRadius = 4.0
Result:
Solution 2 - Ios
SWIFT 3
import UIKit
class ButtonWithShadow: UIButton {
override func draw(_ rect: CGRect) {
updateLayerProperties()
}
func updateLayerProperties() {
self.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
self.layer.shadowOffset = CGSize(width: 0, height: 3)
self.layer.shadowOpacity = 1.0
self.layer.shadowRadius = 10.0
self.layer.masksToBounds = false
}
}
!! Only if you do not need corner radius and shadow simultaneously. Otherwise watch this.
Solution 3 - Ios
Be sure to also set shadowRadius
to 0:
Given a UIButton
property named button
set its backing layer properties like this:
self.button.layer.shadowColor = [UIColor grayColor].CGColor;
self.button.layer.shadowOffset = CGSizeMake(0, 1.0);
self.button.layer.shadowOpacity = 1.0;
self.button.layer.shadowRadius = 0.0;
Solution 4 - Ios
I have created IBInspectable
extension that will help you.
You can directly assign from storyboard
Swift 5
//MARK:- IBInspectable
extension UIView {
@IBInspectable var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
layer.masksToBounds = newValue > 0
}
}
@IBInspectable var borderWidth: CGFloat {
get {
return layer.borderWidth
}
set {
layer.borderWidth = newValue
}
}
@IBInspectable var borderColor: UIColor? {
get {
return UIColor(cgColor: layer.borderColor!)
}
set {
layer.borderColor = newValue?.cgColor
}
}
@IBInspectable
var shadowRadius: CGFloat {
get {
return layer.shadowRadius
}
set {
layer.masksToBounds = false
layer.shadowRadius = newValue
}
}
@IBInspectable
var shadowOpacity: Float {
get {
return layer.shadowOpacity
}
set {
layer.masksToBounds = false
layer.shadowOpacity = newValue
}
}
@IBInspectable
var shadowOffset: CGSize {
get {
return layer.shadowOffset
}
set {
layer.masksToBounds = false
layer.shadowOffset = newValue
}
}
@IBInspectable
var shadowColor: UIColor? {
get {
if let color = layer.shadowColor {
return UIColor(cgColor: color)
}
return nil
}
set {
if let color = newValue {
layer.shadowColor = color.cgColor
} else {
layer.shadowColor = nil
}
}
}
}
Solution 5 - Ios
You can try with this code: (sorry, i only know swift, not obj c. this code will add bottom shadow on your button.
button.layer.masksToBounds = false
button.layer.shadowColor = UIColor(rgb: 0x000000, alpha: 1.0).CGColor
button.layer.shadowOpacity = 1.0
button.layer.shadowRadius = 0
button.layer.shadowOffset = CGSizeMake(0, 1.0)
Solution 6 - Ios
View bottom shadow swift 4.2
viewTop.layer.shadowOffset = CGSize(width: 0, height: 1)
viewTop.layer.shadowColor = UIColor.lightGray.cgColor
viewTop.layer.shadowOpacity = 1
viewTop.layer.shadowRadius = 5
viewTop.layer.masksToBounds = false
Solution 7 - Ios
in swift 2.0 add shadow uiview (uibutton) with code before class declaration or in swift file functions:
extension UIView {
func addShadowView(width:CGFloat=0.2, height:CGFloat=0.2, Opacidade:Float=0.7, maskToBounds:Bool=false, radius:CGFloat=0.5){
self.layer.shadowColor = UIColor.blackColor().CGColor
self.layer.shadowOffset = CGSize(width: width, height: height)
self.layer.shadowRadius = radius
self.layer.shadowOpacity = Opacidade
self.layer.masksToBounds = maskToBounds
}
}
in viewdidload add this code
button.addShadowView()
Solution 8 - Ios
CornerRadius and shadow don't mix well on the same layer. So you will have to embed your "to be cornered" UIButton inside an UIView. The shadow will be applied on this UIView.
The following code, given as an example, produces the image below it:
import UIKit
class CustomButton: UIButton {
required init(coder decoder: NSCoder) {
super.init(coder: decoder)
backgroundColor = UIColor.whiteColor()
}
override func drawRect(rect: CGRect) {
updateLayerProperties()
}
func updateLayerProperties() {
layer.masksToBounds = true
layer.cornerRadius = 12.0
//superview is your optional embedding UIView
if let superview = superview {
superview.backgroundColor = UIColor.clearColor()
superview.layer.shadowColor = UIColor.darkGrayColor().CGColor
superview.layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: 12.0).CGPath
superview.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)
superview.layer.shadowOpacity = 1.0
superview.layer.shadowRadius = 2
superview.layer.masksToBounds = true
superview.clipsToBounds = false
}
}
}
Solution 9 - Ios
Put this method into your UIView extension and play with offset value
func drawShadow(shadowColor: UIColor = UIColor.black, opacity: Float =
0.3, offset: CGSize, radius: CGFloat = 5, shouldRasterize : Bool = false) {
self.layer.shadowColor = shadowColor.cgColor
self.layer.shadowOpacity = opacity
self.layer.shadowOffset = offset
self.layer.shadowRadius = radius
self.layer.shouldRasterize = shouldRasterize
}
Solution 10 - Ios
To add shadow to a button with corner radius:
final class CustomButton: UIButton {
private var shadowLayer: CAShapeLayer!
override func layoutSubviews() {
super.layoutSubviews()
if shadowLayer == nil {
shadowLayer = CAShapeLayer()
shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 33).cgPath
if self.backgroundColor != nil {
shadowLayer.fillColor = self.backgroundColor?.cgColor
}
else{
shadowLayer.fillColor = UIColor.white.cgColor
}
shadowLayer.shadowColor = UIColor.gray.cgColor
shadowLayer.shadowPath = shadowLayer.path
shadowLayer.shadowOffset = CGSize(width: 0.0, height: 3.0)
shadowLayer.shadowOpacity = 0.4
shadowLayer.shadowRadius = 2
layer.insertSublayer(shadowLayer, at: 0)
}
}
}
Solution 11 - Ios
You can try with this code:
LoveButtonOutlet.layer.backgroundColor = UIColor.white.cgColor
LoveButtonOutlet.layer.cornerRadius = 10
LoveButtonOutlet.layer.borderWidth = 2
LoveButtonOutlet.layer.borderColor = UIColor.black.cgColor
LoveButtonOutlet.layer.shadowOffset = CGSize(width: 0, height: 1)
LoveButtonOutlet.layer.shadowColor = UIColor.darkGray.cgColor
LoveButtonOutlet.layer.shadowOpacity = 1
LoveButtonOutlet.layer.shadowRadius = 5
LoveButtonOutlet.layer.masksToBounds = false
Solution 12 - Ios
extension UIButton
{
func setButtonCornerRadiusOnly(getValue:CGFloat)
{
self.layer.cornerRadius = getValue
self.clipsToBounds = true
}
func setButtonBorderColorAndHeight(getHeight:CGFloat,getColor:UIColor)
{
self.layer.borderColor = getColor.cgColor
self.layer.borderWidth = getHeight
}
func setBtnWithShadow()
{
self.layer.shadowOffset = CGSize(width: 0.5, height: 0.4)
self.layer.shadowOpacity = 0.5
self.layer.shadowRadius = 1.5
self.layer.cornerRadius = self.frame.size.height/2
self.layer.masksToBounds = false
}
}