18

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

我想在“父”视图上圆角,并设置一个阴影。我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”已经存在。太棒了。)

4

5 回答 5

22

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

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

于 2011-09-29T19:56:38.607 回答
5

通常,您必须将 clipsToBounds 设置为圆角,但由于您想要保留阴影,因此您还必须将阴影的角设置为圆角。您是否尝试过使用贝塞尔路径设置阴影路径?将 clipsToBounds/masksToBounds 保持为默认值,NO。就像是:

  [[parent layer] setCornerRadius:6.0f];
  [[parent layer] setShadowPath:
             [[UIBezierPath bezierPathWithRoundedRect:[parent bounds] 
                   cornerRadius:6.0f] CGPath]];
于 2010-09-20T15:45:46.293 回答
0

您是否尝试过设置子 UIImageView 的边界以使其也具有圆角?也许那样它就不会覆盖容器视图的阴影。只是一个想法,不确定它是否会起作用。

于 2010-09-26T13:36:34.867 回答
0

使用 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 repo上找到更多将图像与圆角和阴影结合起来的方法。

于 2016-01-03T22:01:57.393 回答
0

如果您想要图像视图的角半径阴影层,那么更好的解决方案是将图像视图作为具有 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)
于 2019-01-06T06:42:39.713 回答