How to mask and add shadow in UIView

I create a custom view that I want to hide and add a shadow to it.

disguise:

let p = UIBezierPath() p.moveToPoint(CGPointMake(20, 20)) p.addLineToPoint(CGPointMake(100, 20)) p.addLineToPoint(CGPointMake(100, 50)) p.addLineToPoint(CGPointMake(110, 55)) p.addLineToPoint(CGPointMake(100, 60)) p.addLineToPoint(CGPointMake(100, 100)) p.addLineToPoint(CGPointMake(20, 100)) p.closePath() let s = CAShapeLayer() s.frame = layer.bounds s.path = p.CGPath s.fillColor = UIColor.greenColor().CGColor layer.mask = s 

disguise works, now I want to add a shadow. but does not work.

I tried adding a shadow to the main layer and nothing happens.

  layer.shadowColor = UIColor.yellowColor().CGColor layer.shadowRadius = 10 layer.shadowOpacity = 0.9 layer.shadowOffset = CGSizeZero 

I tried to add it to the mask layer, and I got the main view, a masked shadow.

  s.shadowColor = UIColor.yellowColor().CGColor s.shadowRadius = 10 s.shadowOpacity = 0.9 s.shadowOffset = CGSizeZero 

Any suggestions for adding this yellow shadow to the hidden view?

thanks

+11
source share
3 answers

Thanks @WilsonXJ I changed the mask to addSubLayer.

This is the answer that worked for me:

  let p = UIBezierPath() p.moveToPoint(CGPointMake(20, 20)) p.addLineToPoint(CGPointMake(100, 20)) p.addLineToPoint(CGPointMake(100, 50)) p.addLineToPoint(CGPointMake(110, 55)) p.addLineToPoint(CGPointMake(100, 60)) p.addLineToPoint(CGPointMake(100, 100)) p.addLineToPoint(CGPointMake(20, 100)) p.closePath() let s = CAShapeLayer() s.fillColor = UIColor.whiteColor().CGColor s.frame = layer.bounds s.path = p.CGPath layer.backgroundColor = UIColor.clearColor().CGColor layer.addSublayer(s) layer.masksToBounds = true layer.shadowColor = UIColor.yellowColor().CGColor layer.shadowOffset = CGSizeZero layer.shadowOpacity = 0.9 layer.shadowPath = p.CGPath layer.shadowRadius = 10 
+8
source

I do not think the current answer is correct because layer.mask no longer used.

In the case when you need to use layer.mask and cast a shadow on the masked layer - the obvious solution is to add another layer below the masked layer, which will have the same shape as layer.mask and cast a shadow

example:

 let view = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 500, height: 500))) view.backgroundColor = .white PlaygroundPage.current.liveView = view let path: CGPath = ... let maskedView = UIView(frame: path.boundingBox) maskedView.center = view.center maskedView.backgroundColor = .green view.addSubview(maskedView) let maskLayer = CAShapeLayer() maskLayer.frame = maskedView.bounds maskLayer.path = path maskedView.layer.mask = maskLayer let shadowLayer = CAShapeLayer() shadowLayer.path = path shadowLayer.frame = maskedView.frame shadowLayer.shadowOpacity = 0.4 shadowLayer.shadowRadius = 2 shadowLayer.shadowColor = UIColor.black.cgColor shadowLayer.shadowOffset = CGSize(width: 4, height: 4) maskedView.superview!.layer.insertSublayer(shadowLayer, below: maskedView.layer) 
0
source

If you do not want your subviews to be covered with a layer, replace:

  layer.addSublayer(s) 

from

  for subview in subviews { layer.insertSublayer(s, below: subview.layer) } 
0
source

All Articles