How to make a drop shadow effect on a label in Swift?

Viewed 41348

I can't figure out how to code a drop shadow on a label. I have a score label that changes so just photoshopping text with shadows wont be possible. I need to code it so it automatically has a blurry shadow behind the text at all times. Can anyone come with some examples or help?


People saying this is a duplicate, the "duplicate" is about drop shadows on UIView, mine is about UILabel. It's not the same thing.

7 Answers

You can write an extension and use it. Place the extension code outside of class ViewController.

I like subtle shadow.
enter image description here

extension UILabel {
    func textDropShadow() {
        self.layer.masksToBounds = false
        self.layer.shadowRadius = 2.0
        self.layer.shadowOpacity = 0.2
        self.layer.shadowOffset = CGSize(width: 1, height: 2)
    }

    static func createCustomLabel() -> UILabel {
        let label = UILabel()
        label.textDropShadow()
        return label
    }
}

On your label simply call this method

myLabel.textDropShadow()

works fine but add shadow to ALL label, not to text.

in this case:

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let shadow = NSShadow()
        shadow.shadowColor = UIColor.blue
        shadow.shadowBlurRadius = 10
        
        let attrs: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 36),
            .foregroundColor: UIColor.red,
            .shadow: shadow
        ]
        
        let s = "MY TEXT"
        let attributedText = NSAttributedString(string: s, attributes: attrs)
        self.label.attributedText = attributedText
    }


}


You will get:

[![enter image description here][1]][1]


  [1]: https://i.stack.imgur.com/CRMpg.png




**note:** You must add attributed string every time, as shadow is an attribute of string, not label, otherwise you can also derive class and override "setText". (keeping attributes inside the object in a a property you can set on init/setter)

Swift 4, IBInspectable using extension

extension UILabel {

    @IBInspectable var isShadowOnText: Bool {
        get {
            return self.isShadowOnText
        }
        set {
            guard (newValue as? Bool) != nil else {
                return
            }

            if newValue == true{

                self.layer.shadowColor = UIColor.black.cgColor
                self.layer.shadowRadius = 2.0
                self.layer.shadowOpacity = 1.0
                self.layer.shadowOffset = CGSize(width: 2, height: 2)
                self.layer.masksToBounds = false
            }
        }
    }
}

Swift 4 - Extension with shadow parameters:

 // Label Shadow
    extension UILabel {
        func lblShadow(color: UIColor , radius: CGFloat, opacity: Float){
            self.textColor = color
            self.layer.masksToBounds = false
            self.layer.shadowRadius = radius
            self.layer.shadowOpacity = opacity

            self.layer.shadowOffset = CGSize(width: 1, height: 1)
            self.layer.shouldRasterize = true
            self.layer.rasterizationScale = UIScreen.main.scale
        }
    }

On your label simply call this method

let titleColor = UIColor(red:0.08, green:0.08, blue:0.08, alpha:1.0)
titleLbl.lblShadow(color: titleColor, radius: 3, opacity: 0.25)

U can make a extension method for all UIView subclasses.

extension UIView {
    func drawShadow(offset: CGSize, opacity: Float = 0.25, color: UIColor = .black, radius: CGFloat = 1) {
        layer.masksToBounds = false
        layer.shadowColor = color.cgColor
        layer.shadowOffset = offset
        layer.shadowOpacity = opacity
        layer.shadowRadius = radius
    }
}
Related