Search code examples
swiftcalayeruibezierpath

Add multiple mask to CALayer (1 is for adding corner)


I want to make UI like this

Custom View

I want this view have rounded corner and shadow on it.

Here is my View hierarchy in Xib:

-Content View 
    - Shadow View
    - Container View
        - Left View
        - Concave View
        - Action View

Here is my snippet to achieve the current UI:

for concaving path:

        let couponPath = UIBezierPath()
        let zeroPoint = CGPoint.zero
        couponPath.move(to: zeroPoint)
        couponPath.addLine(to: CGPoint(x: leftView.frame.width, y: zeroPoint.y))
        let radius = concaveView.frame.width / 2
        let centerX = zeroPoint.x + leftView.frame.width + radius
        couponPath.addArc(withCenter: CGPoint(x: centerX, y: zeroPoint.y), radius: radius, startAngle: CGFloat.pi, endAngle: 0, clockwise: false)
        couponPath.addLine(to: CGPoint(x: containerView.frame.width, y: zeroPoint.y))

        couponPath.addLine(to: CGPoint(x: containerView.frame.width, y: containerView.frame.height))

        couponPath.addArc(withCenter: CGPoint(x: leftView.frame.width + radius, y: containerView.frame.height), radius: radius, startAngle: CGFloat.pi * 0, endAngle: CGFloat.pi, clockwise: false)

        couponPath.addLine(to: CGPoint(x: zeroPoint.x, y: containerView.frame.height))
        couponPath.close()

And then I create CALayer that path is couponPath.

let shapeLayer = CAShapeLayer()
shapeLayer.path = couponPath.cgPath

And I mask it to my containerView: self.containerView.layer.mask = shapeLayer

I tried to add shadow using this code.

let shadowLayer = CAShapeLayer()
shadowLayer.frame = containerView.frame
shadowLayer.path = shapeLayer.path
shadowLayer.shadowOpacity = 0.5
shadowLayer.shadowRadius = 5
shadowLayer.masksToBounds = false
shadowLayer.shadowOffset = CGSize(width: 0, height: 20)
self.shadowView.layer.addSublayer(shadowLayer)

How can I add another masking to corner the radius of container view? And is there better way to add shadow instead of using new View (ShadowView) and apply shadow on it?

Here is my xib and view Gist

Thank you.


Solution

  • I ended up using this answer on stackoverflow with some custom to add shadow and corner on it.

    Here is playground gist