Creating a shadow for a UIImageView that has rounded corners?

前端 未结 5 1377
伪装坚强ぢ
伪装坚强ぢ 2020-11-27 14:17

I am trying to create an ImageView that has rounded corners and a shadow to give it some depth. I was able to create a shadow for the UIImageView,

相关标签:
5条回答
  • 2020-11-27 14:50

    Here is a another solution (tested code) in swift 2.0

    If you set clipsToBounds to true, this will round the corners but prevent the shadow from appearing. So, you can add same size UIView in storyboard behind imageview and we can give shadow to that view

    SWIFT 2.0

    outerView.layer.cornerRadius = 20.0
    outerView.layer.shadowColor = UIColor.blackColor().CGColor
    outerView.layer.shadowOffset = CGSizeMake(0, 2)
    outerView.layer.shadowOpacity = 1
    outerView.backgroundColor = UIColor.whiteColor()
    
    0 讨论(0)
  • 2020-11-27 15:05

    2019

    Finally here is how to

    Properly have an image view, with rounded corners AND shadows.

    It's this simple:

    class ShadowRoundedImageView: UIView {
        @IBInspectable var image: UIImage? = nil {
            didSet {
                imageLayer.contents = image?.cgImage
                shadowLayer.shadowPath = (image == nil) ? nil : shapeAsPath }}
        
        var imageLayer: CALayer = CALayer()
        var shadowLayer: CALayer = CALayer()
        
        var shape: UIBezierPath {
            return UIBezierPath(roundedRect: bounds, cornerRadius:50) }
        
        var shapeAsPath: CGPath {
            return shape.cgPath }
    
        var shapeAsMask: CAShapeLayer {
            let s = CAShapeLayer()
            s.path = shapeAsPath
            return s }
        
        override func layoutSubviews() {
            super.layoutSubviews()
            clipsToBounds = false
            backgroundColor = .clear
            
            self.layer.addSublayer(shadowLayer)
            self.layer.addSublayer(imageLayer) // (in that order)
            
            imageLayer.frame = bounds
            imageLayer.contentsGravity = .resizeAspectFill // (as preferred)
            
            imageLayer.mask = shapeAsMask
            shadowLayer.shadowPath = (image == nil) ? nil : shapeAsPath
            shadowLayer.shadowOpacity = 0.80 // etc ...
        }
    }
    

    Here is the

    Explanation

    1. UIImageView is useless, you use a UIView

    2. You need two layers, one for the shadow and one for the image

    3. To round an image layer you use a mask

    4. To round a shadow layer you use a path

    For the shadow qualities, obviously add code as you see fit

        shadowLayer.shadowOffset = CGSize(width: 0, height: 20)
        shadowLayer.shadowColor = UIColor.purple.cgColor
        shadowLayer.shadowRadius = 5
        shadowLayer.shadowOpacity = 0.80
    

    For the actual shape (the bez path) make it any shape you wish.

    (For example this tip https://stackoverflow.com/a/41553784/294884 shows how to make only one or two corners rounded.)

    Summary

    • Use two layers on a UIView

    Make your bezier and ...

    • Use a mask on the image layer

    • Use a path on the shadow layer

    0 讨论(0)
  • 2020-11-27 15:08

    You can use a simple class I have created to add image with rounded corners and shadow directly from Storyboard

    You can find the class here

    0 讨论(0)
  • 2020-11-27 15:09

    Swift 5:

    You can use the below extension:

    extension UIImageView {
        func applyshadowWithCorner(containerView : UIView, cornerRadious : CGFloat){
            containerView.clipsToBounds = false
            containerView.layer.shadowColor = UIColor.black.cgColor
            containerView.layer.shadowOpacity = 1
            containerView.layer.shadowOffset = CGSize.zero
            containerView.layer.shadowRadius = 10
            containerView.layer.cornerRadius = cornerRadious
            containerView.layer.shadowPath = UIBezierPath(roundedRect: containerView.bounds, cornerRadius: cornerRadious).cgPath
            self.clipsToBounds = true
            self.layer.cornerRadius = cornerRadious
        }
    }
    

    How to use:

    1. Drag a UIView on the storyboard
    2. Drag an ImageView inside that UIView

    Storyboard should look like this:

    1. Create IBOutlet for both Views, call extension on your ImageView, and pass above created UIView as an argument.

    Here is the output :

    0 讨论(0)
  • 2020-11-27 15:10

    If you set clipsToBounds to true, this will round the corners but prevent the shadow from appearing. In order to resolve this, you can create two views. The container view should have the shadow, and its subview should have the rounded corners.

    The container view has clipsToBounds set to false, and has the shadow properties applied. If you want the shadow to be rounded as well, use the UIBezierPath constructor that takes in a roundedRect and cornerRadius.

    let outerView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    outerView.clipsToBounds = false
    outerView.layer.shadowColor = UIColor.black.cgColor
    outerView.layer.shadowOpacity = 1
    outerView.layer.shadowOffset = CGSize.zero
    outerView.layer.shadowRadius = 10
    outerView.layer.shadowPath = UIBezierPath(roundedRect: outerView.bounds, cornerRadius: 10).cgPath
    

    Next, set the image view (or any other type of UIView) to be the same size of the container view, set clipsToBounds to true, and give it a cornerRadius.

    let myImage = UIImageView(frame: outerView.bounds)
    myImage.clipsToBounds = true
    myImage.layer.cornerRadius = 10
    

    Finally, remember to make the image view a subview of the container view.

    outerView.addSubview(myImage)
    

    The result should look something like this:

    0 讨论(0)
提交回复
热议问题