CornerRadius and Shadow on a UIView using @IBInspectable Swift 4.2

4k Views Asked by At

Is it possible to have both CornerRaduis and a shadow on a UIView?

I set up a Custom class for a UIView which uses @IBInspectable to set a cornerRadius and a addShadow which can be true or false. When I set the cornerRadius the shadow doesn't display, if I take away the cornerRadius then it displays again. Thanks in advance!

Custom class:

import UIKit

class CustomUIView: UIView {

    override func awakeFromNib() {
        self.layer.masksToBounds = cornerRadius > 0
    }

    @IBInspectable var useDefaultRadius: Bool = true {
        didSet {
            self.layer.masksToBounds = cornerRadius > 0
        }
    }

    @IBInspectable var cornerRadius: CGFloat {
        set {
            self.layer.cornerRadius = newValue

        }
        get {
            if (useDefaultRadius) {
                    // Set default radius
                    self.layer.cornerRadius = 23
                }

            return self.layer.cornerRadius
        }
    }

    @IBInspectable var addShadow:Bool = true{

        didSet(newValue) {
            if(newValue == true){
                self.layer.masksToBounds = false
                self.layer.shadowColor = UIColor.black.cgColor
                self.layer.shadowOpacity = 0.5
                self.layer.shadowOffset = CGSize(width: 2, height: 3)
                self.layer.shadowRadius = 3

                self.layer.shadowPath = UIBezierPath(rect: bounds).cgPath
                self.layer.shouldRasterize = true
                self.layer.rasterizationScale =  UIScreen.main.scale
                print("trying to use shadow")
            }
        }

    }


}
3

There are 3 best solutions below

3
khush On BEST ANSWER

Rather than creating custom clas and changing class of uiview everytime, i prefer extending it. I'm achieving this by extending UIView as mentioned below:

extension UIView {

    @IBInspectable
    var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        set {
            layer.cornerRadius = newValue
        }
    }

    @IBInspectable
    var borderWidth: CGFloat {
        get {
            return layer.borderWidth
        }
        set {
            layer.borderWidth = newValue
        }
    }

    @IBInspectable
    var borderColor: UIColor? {
        get {
            let color = UIColor.init(cgColor: layer.borderColor!)
            return color
        }
        set {
            layer.borderColor = newValue?.cgColor
        }
    }

    @IBInspectable
    var shadowRadius: CGFloat {
        get {
            return layer.shadowRadius
        }
        set {

            layer.shadowRadius = shadowRadius
        }
    }
    @IBInspectable
    var shadowOffset : CGSize{

        get{
            return layer.shadowOffset
        }set{

            layer.shadowOffset = newValue
        }
    }

    @IBInspectable
    var shadowColor : UIColor{
        get{
            return UIColor.init(cgColor: layer.shadowColor!)
        }
        set {
            layer.shadowColor = newValue.cgColor
        }
    }
    @IBInspectable
    var shadowOpacity : Float {

        get{
            return layer.shadowOpacity
        }
        set {

            layer.shadowOpacity = newValue

        }
    }        
}

And set properties in storyboard as:

enter image description here

That's it.

Hope this helps.

7
Jogendar Choudhary On

Set true masksToBounds in addShadow:Bool or you don't need to set masksToBounds in addShadow:Bool didSet method

@IBInspectable var addShadow:Bool = true{

        didSet(newValue) {
            if(newValue == true){
                //self.layer.masksToBounds = false
                self.layer.masksToBounds = true
                self.layer.shadowColor = UIColor.black.cgColor
                self.layer.shadowOpacity = 0.5
                self.layer.shadowOffset = CGSize(width: 2, height: 3)
                self.layer.shadowRadius = 3

                self.layer.shadowPath = UIBezierPath(rect: bounds).cgPath
                self.layer.shouldRasterize = true
                self.layer.rasterizationScale =  UIScreen.main.scale
                print("trying to use shadow")
            }
        }

    }

You can follow: https://medium.com/bytes-of-bits/swift-tips-adding-rounded-corners-and-shadows-to-a-uiview-691f67b83e4a

https://spin.atomicobject.com/2017/07/18/swift-interface-builder/

0
Michael Maher On

Here's the trick, you have to Set true to masksToBounds then Set false to masksToBounds before adding shadow code. you can check this method to make things clear:

func addShadow(color: UIColor, bottomOrTop: Bool = false, radius: CGFloat = 2, height: CGFloat = 3) {
        // These below line makes the trick to draw shadow with corner radius
        self.layer.masksToBounds = true
        self.layer.masksToBounds = false
        self.layer.shadowOffset = CGSize(width: height, height:  bottomOrTop ? height : height * -1)
        self.layer.shadowRadius = radius
        self.layer.shadowColor = color.cgColor
        self.layer.shadowOpacity = 0.3
    }