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
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.
UIView
, CALayer
and Spring and Strutsimport 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]
}
}
UIView
, UIImageView
, CALayer
and Auto Layoutimport 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:
You can find more ways to combine images with rounded corners and shadow on this Github repo.
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]];
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)
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.
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?.