Question


因為在使用以下兩種方法都會造成在view背後的shadow被裁掉

Answer 1: Make 2 Views


建立兩個View,一個負責shadow,另一個負責border

  1. borderView的masksToBounds設為true(這樣才不會讓borderView的預設效果蓋住shadowView)
  2. shadowView的masksToBounds設為false
borderView.layer.cornerRadius = 10
borderView.layer.masksToBounds = true
        
shadowView.backgroundColor = .clear //與cornerRadius擇一
shadowView.layer.cornerRadius = 10 //與backgroundColor擇一
shadowView.layer.masksToBounds = false
shadowView.layer.shadowColor = UIColor.black.cgColor
shadowView.layer.shadowRadius = 4
shadowView.layer.shadowOpacity = 0.5
shadowView.layer.shadowOffset = CGSize(width: 2, height: 2)

<aside> 💡 但這時候會跑出另一個問題 “The layer is using dynamic shadows which are expensive to render. If possible try setting `shadowPath'” 每次呼叫cell都要render一次陰影效果,很浪費資源因此不建議

</aside>

Answer 2: UIBezierPath


建立一個UIView的subclass,對其override bounds的限制,將陰影效果設於此處

  1. 將該view subclass ShadowView
  2. masksToBounds記得設為false(不然效果都會被蓋掉)
class ShadowView: UIView {
    override var bounds: CGRect {
        didSet {
            setupShadow()
        }
    }
    
    private func setupShadow() {
        self.layer.cornerRadius = 10
        self.layer.shadowOffset = CGSize(width: 0, height: 3)
        self.layer.shadowRadius = 3
        self.layer.shadowOpacity = 0.4
        self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: 10).cgPath
        self.layer.shouldRasterize = true
        self.layer.rasterizationScale = UIScreen.main.scale
    }
}

結果