tiene porque para internet instalar escuchar descargar como buscar iphone objective-c core-animation core-graphics quartz-graphics

porque - radio para iphone



No se puede agregar un radio de esquina y una sombra (4)

El siguiente código de Swift 3 muestra cómo dibujar una sombra y un radio de esquina en una imagen usando CAShapeLayer y CALayer .

import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // constants let radius: CGFloat = 20, offset = 8 let rect = CGRect(x: 0, y: 0, width: 200, height: 200) // roundedView let roundedView = UIView() view.addSubview(roundedView) // shadow layer let shadowLayer = CALayer() shadowLayer.shadowColor = UIColor.darkGray.cgColor shadowLayer.shadowPath = UIBezierPath(roundedRect: rect, cornerRadius: radius).cgPath shadowLayer.shadowOffset = CGSize(width: offset, height: offset) shadowLayer.shadowOpacity = 0.8 shadowLayer.shadowRadius = 2 roundedView.layer.addSublayer(shadowLayer) // mask layer let maskLayer = CAShapeLayer() maskLayer.path = UIBezierPath(roundedRect: rect, cornerRadius: radius).cgPath // image layer let imageLayer = CALayer() imageLayer.mask = maskLayer imageLayer.frame = rect imageLayer.contentsGravity = kCAGravityResizeAspectFill imageLayer.contents = UIImage(named: "image")?.cgImage roundedView.layer.addSublayer(imageLayer) // auto layout roundedView.translatesAutoresizingMaskIntoConstraints = false roundedView.widthAnchor.constraint(equalToConstant: rect.width).isActive = true roundedView.heightAnchor.constraint(equalToConstant: rect.height).isActive = true roundedView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true roundedView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true } }

Este código genera la siguiente pantalla:

El código anterior se puede refactorizar en los siguientes archivos swift:

CustomView.swift

import UIKit class CustomView: UIView { var imageLayer: CALayer! var image: UIImage? { didSet { refreshImage() } } override var intrinsicContentSize: CGSize { return CGSize(width: 200, height: 200) } func refreshImage() { if let imageLayer = imageLayer, let image = image { imageLayer.contents = image.cgImage } } override func layoutSubviews() { super.layoutSubviews() if imageLayer == nil { let radius: CGFloat = 20, offset: CGFloat = 8 let shadowLayer = CALayer() shadowLayer.shadowColor = UIColor.darkGray.cgColor shadowLayer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: radius).cgPath shadowLayer.shadowOffset = CGSize(width: offset, height: offset) shadowLayer.shadowOpacity = 0.8 shadowLayer.shadowRadius = 2 layer.addSublayer(shadowLayer) let maskLayer = CAShapeLayer() maskLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: radius).cgPath imageLayer = CALayer() imageLayer.mask = maskLayer imageLayer.frame = bounds imageLayer.backgroundColor = UIColor.red.cgColor imageLayer.contentsGravity = kCAGravityResizeAspectFill layer.addSublayer(imageLayer) } refreshImage() } }

ViewController.swift

import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let roundedView = CustomView() roundedView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(roundedView) // auto layout let horizontalConstraint = roundedView.centerXAnchor.constraint(equalTo: view.centerXAnchor) let verticalConstraint = roundedView.centerYAnchor.constraint(equalTo: view.centerYAnchor) NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint]) roundedView.image = UIImage(named: "image") } }

Puede encontrar más formas de combinar imágenes con esquinas redondeadas y sombras en este repositorio de Github .

Estoy tratando de dibujar una sombra y un radio de esquina en una imagen. Puedo agregarlos por separado, pero no tengo forma de agregar ambos efectos al mismo tiempo. Estoy agregando una sombra con:

[layer setShadowOffset:CGSizeMake(0, 3)]; [layer setShadowOpacity:0.4]; [layer setShadowRadius:3.0f]; [layer setShouldRasterize:YES];

Aquí, layer es un CALayer de una subclase UIView. Así que esto funciona cada vez que configuro

[layer setMasksToBounds:NO];

Ahora para agregar un radio de esquina hago esto:

[layer setCornerRadius:7.0f];

pero necesito configurar MasksToBounds en YES para que esto funcione:

[layer setMasksToBounds:YES];

¿Hay de todos modos puedo obtener estos dos efectos para agregar?

Gracias por tu tiempo,

Denis


Porque uso un UIButton con una imagen de fondo, ninguna de estas respuestas funcionó para mí. Sigo sin sombras ni bordes redondos en mis botones.

La forma más fácil en mi escenario era simplemente agregar otra vista detrás del botón y agregarle la sombra así:

button.clipsToBounds=YES; button.layer.cornerRadius = 25; UIView *shadowView = [[UIView alloc]initWithFrame:button.frame]; shadowView.backgroundColor = [UIColor whiteColor];//needs this to cast shadow shadowView.layer.cornerRadius = 25; shadowView.clipsToBounds = YES; shadowView.layer.masksToBounds = NO; shadowView.layer.shadowOffset = CGSizeMake(0, 2); shadowView.layer.shadowRadius = 1; shadowView.layer.shadowOpacity = 0.2; [[button superview]addSubview:shadowView]; [[button superview]bringSubviewToFront:button];


Si si hay

Si desea un radio de esquina y una sombra paralela , no active -masksToBounds , sino que establezca el radio de la esquina y establezca la ruta más ancha de la sombra con un rectángulo redondeado. Mantenga el radio de los dos iguales:

[layer setShadowOffset:CGSizeMake(0, 3)]; [layer setShadowOpacity:0.4]; [layer setShadowRadius:3.0f]; [layer setShouldRasterize:YES]; [layer setCornerRadius:12.0f]; [layer setShadowPath: [[UIBezierPath bezierPathWithRoundedRect:[self bounds] cornerRadius:12.0f] CGPath]];

Es posible que desee comprobar su rendimiento sin el conjunto de parámetros -shouldRasterize una vez que esté configurando la ruta de la sombra. El rendimiento del dibujo tiende a ser muy bueno una vez que ha establecido una ruta de sombra.

ACTUALIZAR

No había examinado este problema en bastante tiempo, pero parece que ya no es necesario establecer una shadowPath para que esto funcione. Simplemente configurando cornerRadius y shadowOpacity funcionarán ahora. Creo que este ha sido el caso desde iOS5 (por lo que puedo decir). Proporcionar esta actualización es probablemente innecesario ya que la configuración de esos parámetros "simplemente funciona", pero la proporcionaré para la posteridad. Para resumir, esto es ahora todo lo que necesita:

[layer setShadowOpacity:0.4]; [layer setCornerRadius:12.0f];

Si aún necesita un mejor rendimiento, puede seguir adelante y configurar el parámetro shouldRasterize también:

[layer setShouldRasterize:YES];

Y hablando de rendimiento, vale la pena señalar que si está notando animaciones lentas, querrá usar la técnica de configuración de la ruta de la sombra después de todo. Esta actualización realmente fue solo para señalar que ya no es necesario establecer la ruta para lograr el efecto de mostrar tanto un radio de esquina como una sombra al mismo tiempo. Si el rendimiento es su prioridad, sin embargo, utilice una ruta.

ACTUALIZACIÓN 2

Ya que la gente parece tener problemas para que esto funcione en algunos casos, publicaré aquí un fragmento de código más completo de un proyecto de ejemplo que creé:

- (void)viewDidLoad { [super viewDidLoad]; CALayer *layer = [CALayer layer]; [layer setBounds:CGRectMake(0.0f, 0.0f, 100.0f, 200.0f)]; [layer setPosition:[[self view] center]]; [layer setBackgroundColor:[[UIColor lightGrayColor] CGColor]]; [layer setShadowOpacity:0.55f]; [layer setCornerRadius:8.0f]; [layer setBorderWidth:1.0f]; [[[self view] layer] addSublayer:layer]; [[[self testView] layer] setShadowOpacity:0.55f]; [[[self testView] layer] setShadowRadius:15.0f]; [[[self testView] layer] setCornerRadius:8.0f]; [[[self testView] layer] setBorderWidth:1.0f]; }

El testView es un UIView que agregué en Interface Builder y puse una salida en. Esto es para asegurarse de que funciona igual en las dos capas que agrega explícitamente, así como en las capas dentro de las subvistas.

He probado esto en los simuladores para iOS5 hasta iOS6.1. Me da este resultado en cada uno de ellos:


view.layer.cornerRadius=4; [view.layer setMasksToBounds:YES]; [view.layer setShadowColor:SHADOW_COLOR]; [view.layer setShadowOpacity:4 ]; [view.layer setShadowRadius:4]; [view.layer setShadowOffset:0]; [view.layer setShadowPath: [[UIBezierPath bezierPathWithRoundedRect:[view bounds] cornerRadius:CORNER_RADIUS] CGPath]]; view.layer.borderColor=[[UIColor lightGrayColor] colorWithAlphaComponent:.5].CGColor; view.layer.borderWidth=.4;