ios 为具有圆角的 UIImageView 创建阴影?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41475501/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 11:01:04  来源:igfitidea点击:

Creating a shadow for a UIImageView that has rounded corners?

iosswiftuiviewuiimageviewshadow

提问by John Hodge

I am trying to create an ImageViewthat has rounded corners and a shadow to give it some depth. I was able to create a shadow for the UIImageView, but whenever I added the code to also make it have rounded corners, it only had rounded corners with no shadow. I have an IBOutletnamed myImage, and it is inside of the viewDidLoadfunction. Does anybody have any ideas on how to make it work? What am I doing wrong?

我正在尝试创建一个ImageView具有圆角和阴影的阴影以赋予它一些深度。我能够为 创造一个阴影UIImageView,但是每当我添加代码以使其具有圆角时,它只有圆角而没有阴影。我有一个IBOutletnamed myImage,它在viewDidLoad函数内部。有人对如何使其工作有任何想法吗?我究竟做错了什么?

override func viewDidLoad() {
    super.ViewDidLoad() 
    myImage.layer.shadowColor = UIColor.black.cgColor
    myImage.layer.shadowOpacity = 1 
    myImage.layer.shadowOffset = CGSize.zero
    myImage.layer.shadowRadius = 10
    myImage.layer.shadowPath = UIBezierPath(rect: myImage.bounds).cgPath
    myImage.layer.shouldRasterize = false
    myImage.layer.cornerRadius = 10
    myImage.clipsToBounds = true
}

回答by nathangitter

If you set clipsToBoundsto 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.

如果您设置clipsToBoundstrue,这将使角落变圆但防止出现阴影。为了解决这个问题,您可以创建两个视图。容器视图应该有阴影,它的子视图应该有圆角。

The container view has clipsToBoundsset to false, and has the shadow properties applied. If you want the shadow to be rounded as well, use the UIBezierPathconstructor that takes in a roundedRectand cornerRadius.

容器视图已clipsToBounds设置为false,并应用了阴影属性。如果您希望阴影也被四舍五入,请使用UIBezierPath接受 aroundedRect和的构造函数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 clipsToBoundsto true, and give it a cornerRadius.

接下来,将图像视图(或任何其他类型的UIView)设置clipsToBounds为与容器视图相同的大小,设置为true,并给它一个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:

结果应该是这样的:

enter image description here

在此处输入图片说明

回答by Hardik Thakkar

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

这是 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

如果您将 clipsToBounds 设置为 true,这将圆角但防止出现阴影。因此,您可以在 imageview 后面的故事板中添加相同大小的 UIView,我们可以为该视图提供阴影

SWIFT 2.0

斯威夫特 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()

回答by Surendra Kumar

Swift 5:

斯威夫特 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 storyboard
  2. Drag a ImageView inside that UIView
  1. 在情节提要上拖动 UIView
  2. 在 UIView 中拖动一个 ImageView

Storyboard should look like this:

故事板应如下所示:

enter image description here

在此处输入图片说明

  1. Create IBOutlet for both View, call extension on your ImageView and pass above created UIView as argument.
  1. 为两个视图创建 IBOutlet,在 ImageView 上调用扩展并将上面创建的 UIView 作为参数传递。

Here is the output :

这是输出:

enter image description here

在此处输入图片说明

回答by Fattie

2019

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

  1. UIImageView 没用,你用一个 UIView

  2. 你需要两层,一层用于阴影,一层用于图像

  3. 要使图像层变圆,请使用蒙版

  4. 要使阴影层变圆,请使用路径

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.

对于实际形状(bez 路径),使其成为您想要的任何形状。

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

(例如这个技巧https://stackoverflow.com/a/41553784/294884显示了如何只使一个或两个角变圆。)

Summary

概括

? Use two layers on a UIView

? 在 UIView 上使用两层

Make your bezier and ...

使您的贝塞尔曲线和...

? Use a maskon the image layer

? 在图像层上使用蒙版

? Use a pathon the shadow layer

? 在阴影层上使用路径

回答by George Leonidas

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

您可以使用我创建的简单类直接从 Storyboard 添加带有圆角和阴影的图像

You can find the class here

你可以在这里找到课程

Swift_Shadow_ImageView

Swift_Shadow_ImageView