0

I'm trying to create a shadow on the top a view.
This is my hierarchy:
View
------TablewView
------BottomView

TableView and BottomView have the same parent: View.
I want the BottomView to have a shadow on top of the TableView like the pic on the left, but the result is the one on the right:

enter image description here

If I try to remove the TableView I see the shadow. The BottomView haves rounded corners. This is the BottomView Class:

class BottomView: UIView {
    private var shadowLayer: CAShapeLayer!

    override func layoutSubviews() {
        super.layoutSubviews()

        if shadowLayer == nil {
            let shadowLayer = CAShapeLayer()
            shadowLayer.masksToBounds = false
            //rect is an ex.
            shadowLayer.path =  UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: 200, height: 80), cornerRadius: 9).cgPath
            shadowLayer.fillColor = UIColor.red.cgColor

            shadowLayer.shadowColor = UIColor.black.cgColor
            shadowLayer.shadowPath = shadowLayer.path
            shadowLayer.shadowOffset = CGSize(width: 5, height: -5)
            shadowLayer.shadowOpacity = 1
            shadowLayer.shadowRadius = 3
            shadowLayer.zPosition = 10
            layer.insertSublayer(shadowLayer, at: 0)
            clipsToBounds = false
        }
    }
}
DanielZanchi
  • 2,708
  • 1
  • 25
  • 37

1 Answers1

2

The first issue is variable / object scope...

class BottomView: UIView {
    private var shadowLayer: CAShapeLayer!

    override func layoutSubviews() {
        super.layoutSubviews()

        if shadowLayer == nil {
            let shadowLayer = CAShapeLayer()
            ...

Where you say: let shadowLayer = CAShapeLayer(), you just created a new, local shadowLayer object, and it disappears when it goes out of scope (at the end of the if block).

Change that line to:

shadowLayer = CAShapeLayer()   // remove the let

and you should see your shadow.

You can "automate" the sizing, by adding this below the if block:

    if shadowLayer != nil {
        shadowLayer.path =  UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height), cornerRadius: 9).cgPath
    }

that will re-size the shadow layer anytime the view changes size.

DonMag
  • 69,424
  • 5
  • 50
  • 86