How to add a shadow to a view that's masked with a path

心不动则不痛 提交于 2019-12-12 06:52:28

问题


How do I add a shadow to a view that's masked with a path?

layer has a mask property that you can set like this yourCustomView.layer.mask = somePath. But how do I add a shadow that's also masked to the layer.mask?


回答1:


I see this asked quite a bit and answers are all over the place, so I thought I would centralize a tad.

Basically when you want to add a shadow to a view that's masked with a path, things get interesting.

This is an extension I built that handles it all and is really easy to use. The corners argument is setup for a basic rounded corners setup, but you can replace that with whatever UIBezierPath you want.

import UIKit

public extension UIView {
    /// You will probably need to call this from viewDidLayoutSubviews()
    func roundCorners(corners: UIRectCorner = .bottomRight, radius: CGFloat = 40) {
        layoutIfNeeded()

        let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        self.layer.mask = mask
    }

    /// You will probably need to call this from viewDidLayoutSubviews()
    func roundCornersWithShadow(corners: UIRectCorner = .bottomRight, cornerRadius radius: Double = 40, shadowOpacity: Float = 0.5, shadowRadius: Double = 4, shadowOffset: CGSize = CGSize(width: 0, height: 2), shadowColor: UIColor = .black, maskName: String = "mask", shadowName: String = "shadow") {

        layoutIfNeeded()

        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)).cgPath

        let maskLayer = CAShapeLayer()
        maskLayer.frame = bounds
        maskLayer.path = path
        layer.mask = maskLayer
        layer.name = maskName

        if let subLayers = superview?.layer.sublayers {
            for layer in subLayers where layer.name == shadowName { layer.removeFromSuperlayer() }
        }

        let shadowLayer = CAShapeLayer()
        shadowLayer.name = shadowName
        shadowLayer.path = path
        shadowLayer.frame = frame

        shadowLayer.shadowOpacity = shadowOpacity
        shadowLayer.shadowRadius = CGFloat(shadowRadius)
        shadowLayer.shadowColor = shadowColor.cgColor
        shadowLayer.shadowOffset = shadowOffset

        superview?.layer.insertSublayer(shadowLayer, below: layer)
    }
}

Then use it something like:

override func viewDidLayoutSubviews() {
    ...
    yourView.roundCornersWithShadow(corners: [.bottomRight, .bottomLeft, .topRight, .topLeft]) // Use whatever corners you want.
}


来源:https://stackoverflow.com/questions/56226557/how-to-add-a-shadow-to-a-view-thats-masked-with-a-path

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!