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

时间:2010-09-14 02:10:20

标签: uiview core-animation uiimageview calayer roundedcorners-dropshadow

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

我想围绕“父”视图的角落,并设置投影。我像往常一样在“父母”CALayer上这样做:

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

这会正确显示阴影,但不会使角落变圆。

这是踢球者:

  1. 如果我删除“子”图像视图,或者缩小它以使其不占据“父”视图的整个边界,我会在父级上正确获得圆角和阴影。
  2. 如果我单独留下“孩子”但在“父”视图上设置“clipsToBounds”,我会正确地得到角落。但是现在阴影消失了。
  3. 设置孩子图层上的角半径似乎也没有效果。
  4. 看起来“子”图像视图只是模糊了“父”视图上的圆角,因为它占据了整个矩形,而基于父视图的剪切获得了角落,但也掩盖了阴影。不确定为什么#3不起作用。

    我错过了什么?我是不是一直盯着这个看得太明显的东西?

    感谢。

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

5 个答案:

答案 0 :(得分:21)

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

请参阅Why masksToBounds = YES prevents CALayer shadow?中的答案。

答案 1 :(得分:5)

通常你必须将clipsToBounds设置为圆角,但由于你想要保留阴影,你也必须绕过阴影的角。您是否尝试使用贝塞尔曲线路径设置阴影路径?将clipsToBounds / masksToBounds保持为默认值NO。类似的东西:

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

#1。使用UIViewCALayer和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
    }

}

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

enter image description here

您可以在Github repo找到更多方法将图像与圆角和阴影结合起来。

答案 4 :(得分:0)

如果您希望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)