0

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.

Jefferson Setiawan
  • 536
  • 1
  • 5
  • 22
  • It's very possible THIS: https://stackoverflow.com/a/57465440/294884 will help. i don't 100% understand your need but that's the basic "trick". – Fattie Aug 15 '19 at 16:59

2 Answers2

0

This should help you regarding shadows and rounded corners. You set the shadowView layer rather than adding a sublayer.

class RoundedCornerView: UIView {

    var shadowView: UIView?

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    func setup() {

        // Set the layer of the main view to have rounded corners
        layer.cornerRadius = 12.0
        layer.masksToBounds = true

        // Create a shadow view and its mask
        shadowView = UIView(frame: bounds)
        addSubview(shadowView!)
        sendSubviewToBack(shadowView!)

        shadowView?.layer.shadowColor = UIColor.black.cgColor
        shadowView?.layer.shadowOffset = 4.0
        shadowView?.layer.shadowOpacity = 0.4
        shadowView?.layer.shadowRadius = 12.0
        shadowView?.layer.shadowPath = UIBezierPath(roundedRect: layer.bounds, cornerRadius: layer.cornerRadius).cgPath

        shadowView?.layer.masksToBounds = false
        shadowView?.clipsToBounds = false

    }

}
JonJ
  • 1,061
  • 6
  • 8
0

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

Here is playground gist

Jefferson Setiawan
  • 536
  • 1
  • 5
  • 22