Search code examples
iosswiftuitableviewcalayerbounds

shadow layer going out of bounds in tableview cell


Am trying to add shadow to a view . Currently i have a button and a UIView , where UIView is behind the button with the same frame as button . The constraints for UIView is [top, bottom , leading , trailing] of the button .

The code for adding shadow is as follows :

func applySketchShadow(color: UIColor = .black, alpha: Float = 0.5,
    x: CGFloat = 0, y: CGFloat = 2, blur: CGFloat = 4, spread: CGFloat = 0, bgColor: UIColor = .white){

    let shadowLayer = CAShapeLayer()
    shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: self.bounds.height/2).cgPath
    shadowLayer.fillColor = bgColor.cgColor
    shadowLayer.shadowColor = color.cgColor
    if spread == 0 {
        shadowPath = nil
    } else {
        let dx = -spread
        let rect = bounds.insetBy(dx: dx, dy: dx)
        shadowPath = UIBezierPath(rect: rect).cgPath
    }
    shadowLayer.shadowOffset = CGSize(width: x, height: y)
    shadowLayer.shadowOpacity = alpha
    shadowLayer.shadowRadius = blur / 2.0

    self.insertSublayer(shadowLayer, at: 0)
    self.layoutIfNeeded()
    self.setNeedsLayout()

}

I am calling this code in tableview cell , which has the above mentioned button and view. The code where i am calling the tableview cell function is as follows :

extension GradientButtonCell{

func initCell(topColor : UIColor , bottomColor : UIColor , text : String , orientation : GradientOrientation , textColor : UIColor){

    self.gradientButton.applyGradient(
        withColours: [topColor , bottomColor],
        gradientOrientation: orientation
    )
    self.gradientButton.setTitleColor(textColor, for: .normal)
    self.gradientButton.setTitle(text, for: .normal)
    self.gradientButton.titleLabel?.font = UIFont().nexaBold(withSize: 14.0)
    self.gradientButton.layer.masksToBounds = true
    self.gradientButton.layer.cornerRadius = self.gradientButton.frame.height/2
    self.shadowView.layer.applySketchShadow(
        color: UIColor.hotPink60,
        alpha: 0.6,
        x: 0,
        y: 2,
        blur: 15,
        spread: -20
    )

}

}

But for some reason the shadow layer keeps getting out of bounds like shown in image .

the white layer is going out of bounds from UIView behind the continue button.

Any idea on how to correct this is appreciated.


Solution

  • Add this extension of UIView:

    extension UIView {
        func addShadow(
            backgroundColor: UIColor = .white,
            cornerRadius: CGFloat = 5,
            shadowOpacity: Float = 1,
            shadowRadius: CGFloat = 2,
            shadowColor: UIColor = .lightGray,
            shadowOffset: CGSize = CGSize(width: 1, height: 1)
        ) {
            self.backgroundColor = backgroundColor
            self.layer.masksToBounds = false
            self.layer.cornerRadius = cornerRadius
            self.layer.shadowOpacity = shadowOpacity
            self.layer.shadowRadius = shadowRadius
            self.layer.shadowColor = shadowColor.cgColor
            self.layer.shadowOffset = shadowOffset
        }
    }
    

    Then try to call something like this

    self.shadowView.addShadow(
        backgroundColor: .blue,
        cornerRadius: 10,
        shadowOpacity: 0.7,
        shadowRadius: 5,
        shadowColor: .lightGray,
        shadowOffset: .zero
    )