Search code examples
iosswiftuiviewuibezierpath

Adding shadow to UIView with UIBezierPath


I am creating a custom shape in draw rect method of UIView. It's an arrow and it's working, but I am having trouble adding the shadow. I've tried to add shadow to View itself and also layer but it doesn't work. Any help will be appreciated.

import UIKit

class ArrowView: UIView {

    override func draw(_ rect: CGRect) {
        //Drawing Arrow
        let path = UIBezierPath()
        let edge:CGFloat = 20.0
        path.move(to: CGPoint(x: 0.0, y: 0.0))
        path.addLine(to: CGPoint(x: self.frame.width - edge, y: 0.0))
        path.addLine(to: CGPoint(x: self.frame.width , y: self.frame.height/2))
        path.addLine(to: CGPoint(x: self.frame.width - edge , y: self.frame.height))
        path.addLine(to: CGPoint(x: 0, y: self.frame.height))
        path.close()

        let mask = CAShapeLayer()
        mask.path = path.cgPath
        layer.mask = mask

    }
}

enter image description here


Solution

  • Here is how you can get Shadow

    import UIKit
    
    @IBDesignable
    class ArrowView: UIView {
    
    
        private lazy var arrowLayer : CALayer = {
            let layer = CALayer()
            layer.backgroundColor = UIColor.red.cgColor
            return layer
        }()
    
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            setupView()
        }
    
        required init?(coder: NSCoder) {
            super.init(coder: coder)
    
            setupView()
    
    
        }
        func setupView() {
            self.backgroundColor = .clear
            layer.shadowColor = UIColor.black.cgColor
            layer.shadowOpacity = 1
            layer.shadowOffset = .zero
            layer.shadowRadius = 10
    
    
            layer.addSublayer(arrowLayer)
        }
    
        private func updatePath() {
            let path = UIBezierPath()
            let edge:CGFloat = 20.0
            path.move(to: CGPoint(x: 0.0, y: 0.0))
            path.addLine(to: CGPoint(x: self.bounds.size.width - edge, y: 0.0))
            path.addLine(to: CGPoint(x: self.bounds.size.width , y: self.bounds.size.height/2))
            path.addLine(to: CGPoint(x: self.bounds.size.width - edge , y: self.bounds.size.height))
            path.addLine(to: CGPoint(x: 0, y: self.bounds.size.height))
            path.close()
    
            arrowLayer.frame = self.bounds
    
            let mask = CAShapeLayer()
            mask.path = path.cgPath
    
            arrowLayer.mask = mask
        }
    
        override func layoutSubviews() {
            updatePath()
        }
    
    }
    

    enter image description here