How can I add shadow to a circle UIImageView or UIView?

前端 未结 6 2009
迷失自我
迷失自我 2020-12-25 13:31

I am trying to make a circle UIImageView, and it works. Below is the way I use to make it:

[self.pic.layer setMasksToBounds:YES];
[self.pic.laye         


        
相关标签:
6条回答
  • 2020-12-25 13:45

    Without a container but with a background view here is my 2 cents

    As a swift 2.2 extension

        image?.applyCircleShadow(5, shadowOpacity: 1)
    
    extension UIView {
        func applyCircleShadow(shadowRadius: CGFloat = 2,
                               shadowOpacity: Float = 0.3,
                               shadowColor: CGColor = UIColor.blackColor().CGColor,
                               shadowOffset: CGSize = CGSize.zero) {
            layer.cornerRadius = frame.size.height / 2
            layer.masksToBounds = false
            layer.shadowColor = shadowColor
            layer.shadowOffset = shadowOffset
            layer.shadowRadius = shadowRadius
            layer.shadowOpacity = shadowOpacity
        }
    }
    extension UIImageView {
        override func applyCircleShadow(shadowRadius: CGFloat = 2,
                                        shadowOpacity: Float = 0.3,
                                        shadowColor: CGColor = UIColor.blackColor().CGColor,
                                        shadowOffset: CGSize = CGSize.zero) {
    
            // Use UIImageView.hashvalue as background view tag (should be unique)
            let background: UIView = superview?.viewWithTag(hashValue) ?? UIView()
            background.frame = frame
            background.backgroundColor = backgroundColor
            background.tag = hashValue
            background.applyCircleShadow(shadowRadius, shadowOpacity: shadowOpacity, shadowColor: shadowColor, shadowOffset: shadowOffset)
            layer.cornerRadius = background.layer.cornerRadius
            layer.masksToBounds = true
            superview?.insertSubview(background, belowSubview: self)
        }
    }
    
    0 讨论(0)
  • 2020-12-25 13:48

    I created custom classes (swift 3 or 4) and it works very well :

    class RoundShadowImageView: RoundView {
    
        var imageView = RoundImageView()
    
        var image: UIImage!  {
            didSet {
                imageView.image = image
            }
        }
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            addSubview(imageView)
            needsUpdateConstraints()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            addSubview(imageView)
            needsUpdateConstraints()
        }
    
        override func layoutSubviews() {
            super.layoutSubviews()
    
            clipsToBounds = false
            layer.shadowColor = UIColor.black.cgColor
            layer.shadowOpacity = 0.1
            layer.shadowOffset = CGSize(width: 0, height: 10)
            layer.shadowRadius = 10
            layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: frame.height / 2.0).cgPath
        }
    
        override func updateConstraints() {
            super.updateConstraints()
    
            imageView.snp.makeConstraints { (make) -> Void in
                make.height.width.equalTo(self)
                make.center.equalTo(self)
            }
        }
    }
    
    class RoundImageView: UIImageView {
    
        override func layoutSubviews() {
            super.layoutSubviews()
            let radius: CGFloat = self.bounds.size.height / 2.0
            layer.cornerRadius = radius
            clipsToBounds = true
        }
    }
    
    class RoundView: UIView {
    
        override func layoutSubviews() {
            super.layoutSubviews()
            let radius: CGFloat = self.bounds.size.height / 2.0
            layer.cornerRadius = radius
            clipsToBounds = true
        }
    }
    

    There are 2 classes to make a container and an image view round. And the main class which combines both of them: the one that you'll call.

    0 讨论(0)
  • 2020-12-25 13:48

    I might be a bit late.

    You can easily set the required attributes on the storyboard attribute inspector.

    The result would be something like this.

    0 讨论(0)
  • 2020-12-25 13:49

    In case anyone looks for Swift 3 or 4 working solution:

        let imageSize: CGFloat = 64.0
    
        // Create a container which has a shadow
        let imageCotainer = UIView(frame: CGRect(x: 0, y: 0, width: imageSize, height: imageSize))
        imageCotainer.clipsToBounds = false
        imageCotainer.layer.shadowColor = UIColor.black.cgColor
        imageCotainer.layer.shadowOpacity = 0.2
        imageCotainer.layer.shadowOffset = CGSize(width: 0, height: 1)
        imageCotainer.layer.shadowRadius = 2
    
        // Create an image view that will be inserted into the container view
        let imageView = UIImageView(frame: imageCotainer.bounds)
        imageView.image = yourImage
        imageView.clipsToBounds = true
        let cornerRadius = imageView.frame.height / 2
        imageView.layer.cornerRadius = cornerRadius
    
        // Draw a shadow
        imageCotainer.layer.shadowPath = UIBezierPath(roundedRect: imageCotainer.bounds, cornerRadius: cornerRadius).cgPath
        // Add image into container
        imageCotainer.addSubview(imageView)
    

    Sometimes you also need to set constraints for image inside of the container, but it may work without it too in some cases. But if it's not, add this:

        // Set constraints for the image inside the container view
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.topAnchor.constraint(equalTo: imageCotainer.topAnchor).isActive = true
        imageView.leftAnchor.constraint(equalTo: imageCotainer.leftAnchor).isActive = true
        imageView.rightAnchor.constraint(equalTo: imageCotainer.rightAnchor).isActive = true
        imageView.bottomAnchor.constraint(equalTo: imageCotainer.bottomAnchor).isActive = true
        imageView.heightAnchor.constraint(equalToConstant: imageSize).isActive = true
        imageView.widthAnchor.constraint(equalToConstant: imageSize).isActive = true
    
    0 讨论(0)
  • 2020-12-25 13:52
    extension UIImageView {
        func addShadow() {
            self.layer.shadowColor = UIColor.black.cgColor
            self.layer.shadowOffset = CGSize(width: 2, height: 5)
            self.layer.shadowOpacity = 0.5
            self.layer.shadowRadius = 1.0
            self.clipsToBounds = false
        }
    }
    try this code. hope it will help you....
    
    0 讨论(0)
  • 2020-12-25 13:58

    Use the CALayer's shadowPath property and add a UIBezierPath with rounded rect

    self.pic.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.pic.frame cornerRadius:50.0].CGPath;
    

    EDIT

    For a square-ish image view this technique does not work directly because, as you said, the image view goes back to square. Reason: You set clipsToBounds = NO to show the shadow which removes the clipping for corner radius, where imageView is subview of container.

    Workaround:
    Add your imageview in a container view and then apply the layer shadow to this container. Following is the code I tried.

    [self.imageView.layer setCornerRadius:60.0];
    [self.imageView.layer setMasksToBounds:YES];
    self.imageView.clipsToBounds = YES;
    
    self.container.backgroundColor = [UIColor clearColor];
    self.container.layer.shadowColor = [UIColor blackColor].CGColor;
    self.container.layer.shadowOffset = CGSizeMake(5,15);
    self.container.layer.shadowOpacity = 0.5;
    self.container.layer.shadowRadius = 2.0;
    self.container.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.container.bounds cornerRadius:100.0].CGPath;
    

    The resultant effect is as shown in the screenshot,

    enter image description here

    Hope that helps!

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