Con el siguiente fragmento, agrego un efecto de sombra paralela a uno de mis UIView. Que funciona bastante bien. Pero tan pronto como establezco la propiedad masksToBounds de la vista en YES . El efecto de sombra paralela ya no se procesa.
self.myView.layer.shadowColor = [[UIColor blackColor] CGColor];
self.myView.layer.shadowOpacity = 1.0;
self.myView.layer.shadowRadius = 10.0;
self.myView.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
self.myView.layer.cornerRadius = 5.0;
self.myView.layer.masksToBounds = YES; // <-- This is causing the Drop shadow to not be rendered
UIBezierPath *path = [UIBezierPath bezierPathWithCurvedShadowForRect:self.myView.bounds];
self.myView.layer.shadowPath = path.CGPath;
self.myView.layer.shouldRasterize = YES;
¿Tiene alguna idea sobre esto?
ios
objective-c
uiview
calayer
jchatard
fuente
fuente
Ahora es iOS 6, las cosas podrían haber cambiado. La respuesta de TheSquad no me funciona hasta que logré agregar una línea más
view2.layer.masksToBounds = NO;
, de lo contrario, la sombra no se muestra. Aunque la documentación dicemasksToBounds
NO por defecto, mi código muestra lo contrario.Así es como hago un botón de esquina redondeada con sombra, que se encuentra entre los fragmentos de código más utilizados en mi aplicación.
button.layer.masksToBounds = YES; button.layer.cornerRadius = 10.0f; view.layer.masksToBounds = NO; // critical to add this line view.layer.cornerRadius = 10.0f; view.layer.shadowOpacity = 1.0f; // set shadow path to prevent horrible performance view.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:_button.bounds cornerRadius:10.0f].CGPath; [view addSubview:button];
EDITAR
Si las vistas necesitan ser animadas o desplazadas,
masksToBounds = YES
grava el rendimiento significativamente, lo que significa que la animación probablemente se verá interrumpida. Para obtener esquinas redondeadas y sombras Y una animación o desplazamiento suave, use el siguiente código en su lugar:button.backgroundColor = [UIColor clearColor]; button.layer.backgroundColor = [UIColor redColor].CGColor; button.layer.masksToBounds = NO; button.layer.cornerRadius = 10.0f; view.layer.shadowOpacity = 0.5f; view.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:_button.bounds cornerRadius:10.0f].CGPath; view.layer.shadowOffset = CGSizeMake(0.0f, 4.0f); view.layer.shadowRadius = 2.0f; view.layer.masksToBounds = NO; view.layer.cornerRadius = 10.0f; [view addSubview:button];
fuente
Esta es la versión Swift 3 e IBDesignable de la respuesta publicada por @TheSquad.
Usé el mismo concepto al realizar cambios en el archivo del guión gráfico. Primero moví mi targetView (el que requiere radio de esquina y sombra) dentro de un nuevo containerView . Luego agregué las siguientes líneas de código (Referencia: https://stackoverflow.com/a/35372901/419192 ) para agregar algunos atributos IBDesignable para la clase UIView:
@IBDesignable extension UIView { /* The color of the shadow. Defaults to opaque black. Colors created * from patterns are currently NOT supported. Animatable. */ @IBInspectable var shadowColor: UIColor? { set { layer.shadowColor = newValue!.cgColor } get { if let color = layer.shadowColor { return UIColor(cgColor: color) } else { return nil } } } /* The opacity of the shadow. Defaults to 0. Specifying a value outside the * [0,1] range will give undefined results. Animatable. */ @IBInspectable var shadowOpacity: Float { set { layer.shadowOpacity = newValue } get { return layer.shadowOpacity } } /* The shadow offset. Defaults to (0, -3). Animatable. */ @IBInspectable var shadowOffset: CGPoint { set { layer.shadowOffset = CGSize(width: newValue.x, height: newValue.y) } get { return CGPoint(x: layer.shadowOffset.width, y:layer.shadowOffset.height) } } /* The blur radius used to create the shadow. Defaults to 3. Animatable. */ @IBInspectable var shadowRadius: CGFloat { set { layer.shadowRadius = newValue } get { return layer.shadowRadius } } /* The corner radius of the view. */ @IBInspectable var cornerRadius: CGFloat { set { layer.cornerRadius = newValue } get { return layer.cornerRadius } }
Después de agregar este código, volví al guión gráfico y al seleccionar mi containerView ahora pude encontrar un nuevo conjunto de atributos en el inspector de atributos:
Además de agregar valores para estos atributos según mi elección, también agregué un radio de esquina a mi targetView y establecí la propiedad masksToBounds como verdadera.
Espero que esto ayude :)
fuente
Versión Swift 3.0 con StoryBoard
La misma idea con @TheSquad. Cree una nueva vista debajo de la vista actual y agregue sombra a la vista inferior.
1. Cree una vista debajo de la vista real.
Arrastre
UIView
a StoryBoard con la misma restricción que su vista de destino. Marque el clip para enlazar con la vista de destino. También asegúrese de que la nueva vista esté listada antes de la vista de destino para que la vista de destino cubra la nueva vista.2. Ahora vincule la nueva vista a su código agregue agregar sombra en ella
Esto es solo una muestra. Puedes hacer lo que quieras aquí
shadowView.layer.masksToBounds = false shadowView.layer.shadowColor = UIColor.red.cgColor shadowView.layer.shadowOpacity = 0.5 shadowView.layer.shadowOffset = CGSize(width: -1, height: 1) shadowView.layer.shadowRadius = 3 shadowView.layer.shadowPath = UIBezierPath(rect: coverImage.bounds).cgPath shadowView.layer.shouldRasterize = true
fuente
También tuve problemas drásticos de rendimiento con sombras y esquinas redondeadas. En lugar de usar la parte shadowPath, usé las siguientes líneas que resolvieron perfectamente el impacto de rendimiento:
self.layer.shouldRasterize = YES; self.layer.rasterizationScale = UIScreen.mainScreen.scale;
fuente
Esta es una de las soluciones:
@IBOutlet private weak var blockView: UIView! { didSet { blockView.backgroundColor = UIColor.white blockView.layer.shadowColor = UIColor.black.cgColor blockView.layer.shadowOpacity = 0.5 blockView.layer.shadowOffset = CGSize.zero blockView.layer.cornerRadius = 10 } } @IBOutlet private weak var imageView: UIImageView! { didSet { imageView.layer.cornerRadius = 10 imageView.layer.masksToBounds = true imageView.layer.shouldRasterize = true } }
fuente