How to mask and add shadow to a UIView
Asked Answered
I

2

16

I'm making a custom view that i want to mask and to add shadow to it.

the masking:

    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

the masking works, now i want to add a shadow. but its not working.

i tried to add 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 masked with a shadow.

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

Any suggestions how to add this yellow shadow to the masked view?

Thanks

Imbecility answered 1/6, 2016 at 11:43 Comment(7)
Make sure that your view does't have a zero frameTabriz
It doesn't , i can see the view but there is no shadowImbecility
did you really want a mask not a sublayer ?Agog
@WilsonXJ i changed it to addSubLayer and it works but now my shape is black. and i the color isnt changingImbecility
@WilsonXJ works great . thanksImbecility
you can put an image and describe what effect you wantAgog
@WilsonXJ see my answer, Thanks againImbecility
I
11

Thanks @WilsonXJ I changed 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
Imbecility answered 1/6, 2016 at 12:45 Comment(1)
Subviews is hiding ,,,,Reform
U
4

I don't think that current answer is the right one, because there is no layer.mask usage anymore.

In case when you need to use layer.mask and to drop shadow of masked layer - the obvious solution is to add another layer below masked layer that will have same shape as layer.mask and drop it's 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)
Upheave answered 16/11, 2018 at 12:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.