无法在图像视图拉伸到其边界的图层上设置cornerRadius和阴影?

发布于 2024-09-19 01:18:34 字数 742 浏览 3 评论 0原文

这让我难住了。我有一个 UIView (称之为“父级”)。该视图的最底部子视图是 UIImageView(称为“子视图”),其框架占据整个“父”边界。

我想在“父”视图上圆角,并设置阴影。我像往常一样在“parent”的 CALayer 上执行此操作:

[[parent layer] setShadowOffset:CGSizeMake(5, 5)];
[[parent layer] setShadowRadius:6];
[[parent layer] setShadowOpacity:0.4];    
[[parent layer] setCornerRadius:6];

这正确显示了阴影,但没有圆角。

关键在于:

  1. 如果我删除“子”图像视图,或缩小它,使其不占据“父”视图的整个边界,我就能在父视图上正确获得圆角和阴影。
  2. 如果我保留“子”视图,但在“父”视图上设置“clipsToBounds”,我会正确地得到角点。但现在影子已经消失了。
  3. 子层上设置角半径似乎也没有效果。

看起来“子”图像视图只是模糊了“父”视图上的圆角,因为它占据了整个矩形,并且基于父视图的剪切得到了角,但也掩盖了阴影。不知道为什么#3 不起作用。

我缺少什么?我是否因为盯着这个问题太久而忽略了一些显而易见的事情?

谢谢。

(令人震惊的是,标签“roundedcorners-dropshadow”已经存在。太棒了。)

This is stumping me. I have a UIView (call it "parent"). The bottommost subview of that view is a UIImageView (call it "child"), whose frame occupies the entirety of the "parent" bounds.

I want to round the corners on the "parent" view, and set a drop shadow. I do this on the CALayer of "parent" as usual:

[[parent layer] setShadowOffset:CGSizeMake(5, 5)];
[[parent layer] setShadowRadius:6];
[[parent layer] setShadowOpacity:0.4];    
[[parent layer] setCornerRadius:6];

This shows the shadow correctly, but does not round the corners.

Here's the kicker:

  1. If I remove the "child" image view, or shrink it so it doesn't occupy the whole bounds of the "parent" view, I get the rounded corners and shadow correctly on the parent.
  2. If I leave the "child" alone but set "clipsToBounds" on the "parent" view, I get the corners correctly. But now the shadow's gone.
  3. Setting the corner radius on the layer of the child as well seems to have no effect.

It seems like the "child" image view is just obscuring the rounded corners on the "parent" view since it takes up the whole rect, and clipping based on the parent view gets the corners but also masks off the shadow. Not sure why #3 doesn't work.

What am I missing? Have I been overlooking something obvious by staring at this too long?

Thanks.

(Shockingly, the tag "roundedcorners-dropshadow" already exists. Awesome.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

猥琐帝 2024-09-26 01:18:34

您将需要两个嵌套视图,内部视图设置圆角并剪切到边界,外部视图具有阴影(因此不剪切)。在您的情况下,内部和外部视图可能是“子”和“父”,但我猜您没有为这些视图设置正确的剪切值?

请参阅为什么 maskToBounds = YES 会阻止 CALayer 阴影?中的答案。

You will need two nested views, the inner one setting rounded corners and clipping to bound, and the outer view having the shadow (and therefore not clipping). In your case inner and outer view will probably be "child" and "parent", but I guess you didn't set the right clipping values for these views?

See the answer in Why masksToBounds = YES prevents CALayer shadow?.

注定孤独终老 2024-09-26 01:18:34

通常,您必须将 ClipsToBounds 设置为圆角,但由于您想保留阴影,因此也必须将阴影的角设置为圆角。您是否尝试过使用贝塞尔路径设置阴影路径?将 ClipsToBounds/masksToBounds 保留为默认值“NO”。像这样的东西:

  [[parent layer] setCornerRadius:6.0f];
  [[parent layer] setShadowPath:
             [[UIBezierPath bezierPathWithRoundedRect:[parent bounds] 
                   cornerRadius:6.0f] CGPath]];

Normally you have to set clipsToBounds to have rounded corners, but since you want to retain the shadow you have to round the corners of the shadow as well. Have you tried setting the shadow path using a bezier path? Keep clipsToBounds/masksToBounds to the default, NO. Something like:

  [[parent layer] setCornerRadius:6.0f];
  [[parent layer] setShadowPath:
             [[UIBezierPath bezierPathWithRoundedRect:[parent bounds] 
                   cornerRadius:6.0f] CGPath]];
撧情箌佬 2024-09-26 01:18:34

您是否尝试过设置子 UIImageView 的边界,使其也具有圆角?也许它不会覆盖容器视图的阴影。只是一个想法,不知道是否可行。

Have you tried setting the bounds of the child UIImageView so that it also has rounded corners? Perhaps then it wouldn't override the shadow of the container view. Just a thought, not sure if it will work.

被翻牌 2024-09-26 01:18:34

使用 Swift 3,您可以选择以下两个代码片段之一,以便在图像视图或包含图像图层的视图上设置cornerRadius 和阴影。


#1.使用 UIView、CALayer 以及 Spring 和 Struts

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // constants
        let radius: CGFloat = 20, dimension: CGFloat = 200, offset = 8
        let frame = CGRect(x: 0, y: 0, width: 200, height: 200)

        // custom view
        let customView = UIView(frame: frame)
        customView.contentMode = .scaleAspectFill

        // image layer
        let imageLayer = CALayer()
        imageLayer.contentsGravity = kCAGravityResizeAspectFill
        imageLayer.contents = UIImage(named: "image")!.cgImage
        imageLayer.masksToBounds = true
        imageLayer.frame = frame
        imageLayer.cornerRadius = radius
        imageLayer.masksToBounds = true

        // rounded layer
        let roundedLayer = CALayer()
        roundedLayer.shadowColor = UIColor.darkGray.cgColor
        roundedLayer.shadowPath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: dimension, height: dimension), cornerRadius: radius).cgPath
        roundedLayer.shadowOffset = CGSize(width: offset, height: offset)
        roundedLayer.shadowOpacity = 0.8
        roundedLayer.shadowRadius = 2
        roundedLayer.frame = frame

        // views and layers hierarchy
        customView.layer.addSublayer(imageLayer)
        customView.layer.insertSublayer(roundedLayer, below: imageLayer)
        view.addSubview(customView)

        // layout
        customView.center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
        customView.autoresizingMask = [UIViewAutoresizing.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin]
    }

}

#2。使用 UIViewUIImageViewCALayer 和自动布局

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // constants
        let radius: CGFloat = 20, dimension: CGFloat = 200, offset = 8

        // image view
        let imageView = UIImageView(image: UIImage(named: "image"))
        imageView.contentMode = .scaleAspectFill
        imageView.layer.cornerRadius = radius
        imageView.layer.masksToBounds = true

        // rounded view
        let roundedView = UIView()
        roundedView.layer.shadowColor = UIColor.darkGray.cgColor
        roundedView.layer.shadowPath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: dimension, height: dimension), cornerRadius: radius).cgPath
        roundedView.layer.shadowOffset = CGSize(width: offset, height: offset)
        roundedView.layer.shadowOpacity = 0.8
        roundedView.layer.shadowRadius = 2

        // views hierarchy
        roundedView.addSubview(imageView)
        view.addSubview(roundedView)

        // layout
        imageView.translatesAutoresizingMaskIntoConstraints = false
        roundedView.translatesAutoresizingMaskIntoConstraints = false
        roundedView.widthAnchor.constraint(equalToConstant: dimension).isActive = true
        roundedView.heightAnchor.constraint(equalToConstant: dimension).isActive = true
        imageView.widthAnchor.constraint(equalTo: roundedView.widthAnchor).isActive = true
        imageView.heightAnchor.constraint(equalTo: roundedView.heightAnchor).isActive = true
        roundedView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        roundedView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        imageView.centerXAnchor.constraint(equalTo: roundedView.centerXAnchor).isActive = true
        imageView.centerYAnchor.constraint(equalTo: roundedView.centerYAnchor).isActive = true
    }

}

这两个代码片段都会生成以下显示:

在此处输入图像描述


您可以找到更多在此 Github 存储库

With Swift 3, you can choose one of the two following code snippets in order to set cornerRadius and shadow on an image view or on a view that contains an image layer.


#1. Using UIView, CALayer and Spring and Struts

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // constants
        let radius: CGFloat = 20, dimension: CGFloat = 200, offset = 8
        let frame = CGRect(x: 0, y: 0, width: 200, height: 200)

        // custom view
        let customView = UIView(frame: frame)
        customView.contentMode = .scaleAspectFill

        // image layer
        let imageLayer = CALayer()
        imageLayer.contentsGravity = kCAGravityResizeAspectFill
        imageLayer.contents = UIImage(named: "image")!.cgImage
        imageLayer.masksToBounds = true
        imageLayer.frame = frame
        imageLayer.cornerRadius = radius
        imageLayer.masksToBounds = true

        // rounded layer
        let roundedLayer = CALayer()
        roundedLayer.shadowColor = UIColor.darkGray.cgColor
        roundedLayer.shadowPath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: dimension, height: dimension), cornerRadius: radius).cgPath
        roundedLayer.shadowOffset = CGSize(width: offset, height: offset)
        roundedLayer.shadowOpacity = 0.8
        roundedLayer.shadowRadius = 2
        roundedLayer.frame = frame

        // views and layers hierarchy
        customView.layer.addSublayer(imageLayer)
        customView.layer.insertSublayer(roundedLayer, below: imageLayer)
        view.addSubview(customView)

        // layout
        customView.center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
        customView.autoresizingMask = [UIViewAutoresizing.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin]
    }

}

#2. Using UIView, UIImageView, CALayer and Auto Layout

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // constants
        let radius: CGFloat = 20, dimension: CGFloat = 200, offset = 8

        // image view
        let imageView = UIImageView(image: UIImage(named: "image"))
        imageView.contentMode = .scaleAspectFill
        imageView.layer.cornerRadius = radius
        imageView.layer.masksToBounds = true

        // rounded view
        let roundedView = UIView()
        roundedView.layer.shadowColor = UIColor.darkGray.cgColor
        roundedView.layer.shadowPath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: dimension, height: dimension), cornerRadius: radius).cgPath
        roundedView.layer.shadowOffset = CGSize(width: offset, height: offset)
        roundedView.layer.shadowOpacity = 0.8
        roundedView.layer.shadowRadius = 2

        // views hierarchy
        roundedView.addSubview(imageView)
        view.addSubview(roundedView)

        // layout
        imageView.translatesAutoresizingMaskIntoConstraints = false
        roundedView.translatesAutoresizingMaskIntoConstraints = false
        roundedView.widthAnchor.constraint(equalToConstant: dimension).isActive = true
        roundedView.heightAnchor.constraint(equalToConstant: dimension).isActive = true
        imageView.widthAnchor.constraint(equalTo: roundedView.widthAnchor).isActive = true
        imageView.heightAnchor.constraint(equalTo: roundedView.heightAnchor).isActive = true
        roundedView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        roundedView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        imageView.centerXAnchor.constraint(equalTo: roundedView.centerXAnchor).isActive = true
        imageView.centerYAnchor.constraint(equalTo: roundedView.centerYAnchor).isActive = true
    }

}

Both code snippets generate the following display:

enter image description here


You can find more ways to combine images with rounded corners and shadow on this Github repo.

眼眸 2024-09-26 01:18:34

如果你想要 imageview 具有角半径的阴影层,更好的解决方案是将 imageview 视图作为具有 1 点边距的子视图..并且

 imgBrandLogo.backgroundColor = UIColor.blue
    imgBrandLogo.layer.cornerRadius = imgBrandLogo.frame.height/2
    imgBrandLogo.clipsToBounds = true
    viewBrandLogo.layer.shadowColor = UIColor(rgb:0x262626,alpha:0.24).cgColor
    viewBrandLogo.layer.shadowOffset = CGSize(width: 0, height: 1)
    viewBrandLogo.layer.shadowOpacity = 1
    viewBrandLogo.layer.shadowPath = UIBezierPath(roundedRect:imgBrandLogo.bounds , cornerRadius: imgBrandLogo.frame.height/2).cgPath
    viewBrandLogo.backgroundColor = UIColor.clear.withAlphaComponent(0.0)

If you want shadow layer with corner radius for imageview is that better solution put imageview a view as subview with 1 point margin.. and

 imgBrandLogo.backgroundColor = UIColor.blue
    imgBrandLogo.layer.cornerRadius = imgBrandLogo.frame.height/2
    imgBrandLogo.clipsToBounds = true
    viewBrandLogo.layer.shadowColor = UIColor(rgb:0x262626,alpha:0.24).cgColor
    viewBrandLogo.layer.shadowOffset = CGSize(width: 0, height: 1)
    viewBrandLogo.layer.shadowOpacity = 1
    viewBrandLogo.layer.shadowPath = UIBezierPath(roundedRect:imgBrandLogo.bounds , cornerRadius: imgBrandLogo.frame.height/2).cgPath
    viewBrandLogo.backgroundColor = UIColor.clear.withAlphaComponent(0.0)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文