uiview - ¿No se puede establecer CornerRadius AND shadow on layer que tenga una vista de imagen extendida a sus límites?
core-animation uiimageview (5)
¿Ha intentado establecer los límites de la UIImageView secundaria para que también tenga esquinas redondeadas? Tal vez entonces no anularía la sombra de la vista del contenedor. Sólo un pensamiento, no estoy seguro de si funcionará.
Esto me está parando. Tengo un UIView (llámelo "padre"). La subvista inferior de esa vista es un UIImageView (llámelo "hijo"), cuyo marco ocupa la totalidad de los límites "principales".
Quiero redondear las esquinas en la vista "principal" y establecer una sombra paralela. Hago esto en el CALayer
de "padre" como de costumbre:
[[parent layer] setShadowOffset:CGSizeMake(5, 5)];
[[parent layer] setShadowRadius:6];
[[parent layer] setShadowOpacity:0.4];
[[parent layer] setCornerRadius:6];
Esto muestra la sombra correctamente, pero no redondea las esquinas.
Aquí está el kicker:
- Si elimino la vista de imagen "secundaria", o la contrajo para que no ocupe todos los límites de la vista "primaria", obtengo las esquinas redondeadas y la sombra correctamente en la matriz.
- Si dejo el "hijo" solo pero pongo "clipsToBounds" en la vista "padre", obtengo las esquinas correctamente. Pero ahora la sombra se ha ido.
- Establecer el radio de la esquina en la capa del niño también parece no tener efecto.
Parece que la vista de la imagen "secundaria" simplemente está oscureciendo las esquinas redondeadas de la vista "primaria", ya que ocupa todo el rectángulo, y el recorte basado en la vista principal obtiene las esquinas, pero también se enmascara de la sombra. No estoy seguro de por qué el # 3 no funciona.
¿Qué me estoy perdiendo? ¿He estado pasando por alto algo obvio al mirar esto demasiado tiempo?
Gracias.
(Sorprendentemente, la etiqueta "roundedcorners-dropshadow" ya existe. Impresionante.)
Con Swift 3, puede elegir uno de los dos fragmentos de código siguientes para establecer cornerRadius y shadow en una vista de imagen o en una vista que contenga una capa de imagen.
# 1. Usando UIView
, CALayer
y 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. Usando UIView
, UIImageView
, CALayer
y 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
}
}
Ambos fragmentos de código generan la siguiente visualización:
Puede encontrar más formas de combinar imágenes con esquinas redondeadas y sombras en este repositorio de Github .
Necesitará dos vistas anidadas, la interior con esquinas redondeadas y recorte a encuadernación, y la vista exterior con la sombra (y, por lo tanto, no recorte). En su caso, la vista interna y externa probablemente será "secundaria" y "primaria", pero supongo que no estableció los valores de recorte correctos para estas vistas.
Vea la respuesta en ¿Por qué masksToBounds = YES previene la sombra de CALayer? .
Normalmente, tiene que configurar clipsToBounds para que tenga esquinas redondeadas, pero como desea conservar la sombra, también debe redondear las esquinas de la sombra. ¿Has intentado configurar la ruta de la sombra utilizando una ruta de bezier? Mantenga clipsToBounds / masksToBounds a los valores predeterminados, NO. Algo como:
[[parent layer] setCornerRadius:6.0f];
[[parent layer] setShadowPath:
[[UIBezierPath bezierPathWithRoundedRect:[parent bounds]
cornerRadius:6.0f] CGPath]];
Si desea una capa de sombra con un radio de esquina para la visualización de la imagen, es la mejor solución poner una vista de la vista de una vista como una subvista con un margen de 1 punto ... y
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)