在具有与视图相同的角半径的 UIView 上应用阴影

问题描述:

您好,我有一些带圆角的视图,我想为这些视图添加阴影.

Hello i have some views with rounded corners, and I'd like to apply a shadow to this views.

所以首先我绕过视图:

view.layer.cornerRadius = 15
view.clipsToBounds = true

然后我应用阴影:

    func dropShadow(scale: Bool = true) {
        self.layer.masksToBounds = false
        self.layer.cornerRadius = 15
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius).cgPath
        self.layer.shadowOffset = CGSize(width: 3, height: 3)
        self.layer.shadowOpacity = 0.5
        self.layer.shadowRadius = 5
    }

view.dropShadow()

我的圆形视图带有阴影,但阴影不像我的视图那样圆形.阴影一点也不圆滑

I got my rounded view with a shadow but the shadow is not rounded like my view. The shadow is not rounded at all

您不能从 clipsToBoundstrue 的视图投射阴影.如果视图的 masksToBoundstrue,则其 clipsToBoundstrue;它们是同一回事.

You cannot cast a shadow from a view whose clipsToBounds is true. If a view's masksToBounds is true, its clipsToBounds is true; they are the same thing.

如果您希望从剪辑的视图中出现阴影,您需要使用两个视图:一个用户可以看到的视图,带有圆角和 clipsToBounds 设置为 true,另一个用户 无法 看到,因为它在 后面 第一个,也有圆角,但是clipsToBounds 设置为 false,以投射阴影.

If you want a shadow to appear to come from from a view that clips, you need to use two views: one that the user can see, with rounded corners and clipsToBounds set to true, and another that the user can't see because it's behind the first one, also with rounded corners, but with clipsToBounds set to false, to cast the shadow.

class ShadowView : UIView {
    override init(frame: CGRect) {
        super.init(frame:frame)
        self.isOpaque = true
        self.backgroundColor = .black
        self.dropShadow()
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    func dropShadow() {
        self.layer.masksToBounds = false
        self.layer.cornerRadius = 15
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowOffset = CGSize(width: 3, height: 3)
        self.layer.shadowOpacity = 0.5
        self.layer.shadowRadius = 5
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let r = CGRect(x: 100, y: 100, width: 100, height: 100)
        let v = UIImageView(frame:r)
        v.image = UIImage(named:"marsSurface.jpg")
        v.clipsToBounds = true
        v.backgroundColor = .red
        v.layer.cornerRadius = 15
        self.view.addSubview(ShadowView(frame:r))
        self.view.addSubview(v)
    }
}

请注意,这两个视图都不是另一个视图的子视图,也没有一个可以剪辑的超视图,因为会剪辑阴影.

Note that neither view is a subview of the other, nor do they have a superview that clips, as that would clip the shadow.