Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
834 views
in Technique[技术] by (71.8m points)

swift - Apply a shadow on a UIView that have same corner radius than view

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

SO first I round the view :

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

then I apply the shadow :

    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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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.

enter image description here

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...