Redondea esquinas específicas y muestra la sombra solo en lados específicos.

Tengo la siguiente pieza de código para networkingondear solo las esquinas específicas de una vista:

- (void)roundOnlySpecifiedCornersInView:(UIView *)view corners:(UIRectCorner)corners { UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:(corners) cornerRadii:CGSizeMake(4.0, 4.0)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; maskLayer.path = maskPath.CGPath; view.layer.mask = maskLayer; } 

Esto funciona perfectamente en aislamiento. Ahora también quiero sombra en mi opinión, pero específicamente quiero aplicar sombra en diferentes casos:

  • por todos lados
  • todos los lados excepto el background
  • todos los lados, excepto la parte superior
  • solo lados izquierdo / derecho

Todas las técnicas que encontré funcionan creando un recuadro de la vista. El problema con esto, es que, por ejemplo, solo quieres mantener la sombra en los lados izquierdo / derecho, compensas el background y la parte superior. Como el Rect ahora es less alto, la sombra a la izquierda y la derecha no cubre la altura completa de la vista. Además, la capa de máscara utilizada para networkingondear las esquinas hace que la sombra ya no aparezca.

Código de ejemplo para esto:

  innerView.layer.shadowColor = [[UIColor colorWithWhite:0.0f alpha:0.1f] CGColor]; innerView.layer.shadowOpacity = 1.0f; innerView.layer.shadowOffset = CGSizeMake(0.0f, 0.0f); innerView.layer.shadowRadius = 6.0f; CGRect shadowFrame = UIEdgeInsetsInsetRect(innerView.bounds, UIEdgeInsetsMake(9, 0, 9, 0)); CGPathRef shadowPath = [UIBezierPath bezierPathWithRect:shadowFrame].CGPath; innerView.layer.shadowPath = shadowPath; 

¿Cómo puedo networkingondear esquinas específicas en una vista y al mismo time mostrar la sombra solo en los lados especificados?

¡Las respuestas en Swift también son apreciadas!

Captura de pantalla de lo que quiero (esta es fácil ya que todas las esquinas deben networkingondearse, por lo que puedo usar .layer.cornerRadius y tiene sombra en todos los lados): introduzca la descripción de la imagen aquí

Ahora solo quiero networkingondear solo 2 de las esquinas (arriba a la izquierda y arriba a la derecha, abajo a la izquierda y abajo a la derecha) y agregar sombra a solo algunos lados.

No estoy seguro si cumple con tu demanda. El código crea una image con la sombra superior e inferior, y toda la esquina networkingondeada, puedes modificar el código para lograr lo que necesitas. Puede usar la image como background de su celda (Parece que es UITableViewCell )

Déjame saber si no te funciona.

La image:

introduzca la descripción de la imagen aquí

 // create a shadow image CGSize size = CGSizeMake(ScreenWidth, ScreenWidth); UIGraphicsBeginImageContextWithOptions(size, NO, 0); CGContextRef context = UIGraphicsGetCurrentContext(); UIColor *backgroundColor = [UIColor colorWithRed:246.0/255.0 green:246.0/255.0 blue:246.0/255.0 alpha:1.0]; UIColor *fillColor = [UIColor whiteColor]; CGRect rect = CGRectMake(10, 10, 100, 44); // re-draw the background CGContextSetFillColorWithColor(context, backgroundColor.CGColor); CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height)); // set top and bottom shadow CGRect rectTop = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, 5); CGContextSaveGState(context); CGContextSetShadowWithColor(context, CGSizeMake(0, -5), 5, [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor); CGContextSetFillColorWithColor(context, [UIColor networkingColor].CGColor); CGContextFillRect(context, rectTop); CGContextRestoreGState(context); CGRect rectBottom = CGRectMake(rect.origin.x, rect.origin.y+rect.size.height-5, rect.size.width, 5); CGContextSaveGState(context); CGContextSetShadowWithColor(context, CGSizeMake(0, 5), 5, [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor); CGContextSetFillColorWithColor(context, [UIColor networkingColor].CGColor); CGContextFillRect(context, rectBottom); CGContextRestoreGState(context); // re-draw the background CGContextSetFillColorWithColor(context, backgroundColor.CGColor); CGContextFillRect(context, rect); CGContextSaveGState(context); UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(4.0, 4.0)]; [maskPath addClip]; CGContextSetFillColorWithColor(context, fillColor.CGColor); CGContextFillRect(context, rect); CGContextRestoreGState(context); 

Puede modificar el código para get una sombra izquierda superior:

introduzca la descripción de la imagen aquí

 // create a shadow image CGSize size = CGSizeMake(ScreenWidth, ScreenWidth); UIGraphicsBeginImageContextWithOptions(size, NO, 0); CGContextRef context = UIGraphicsGetCurrentContext(); UIColor *backgroundColor = [UIColor colorWithRed:246.0/255.0 green:246.0/255.0 blue:246.0/255.0 alpha:1.0]; UIColor *fillColor = [UIColor whiteColor]; CGRect rect = CGRectMake(10, 10, 100, 44); // re-draw the background CGContextSetFillColorWithColor(context, backgroundColor.CGColor); CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height)); // set top and left shadow CGRect rectTop = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, 5); CGContextSaveGState(context); CGContextSetShadowWithColor(context, CGSizeMake(0, -5), 5, [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor); CGContextSetFillColorWithColor(context, [UIColor networkingColor].CGColor); CGContextFillRect(context, rectTop); CGContextRestoreGState(context); CGRect rectLeft = CGRectMake(rect.origin.x, rect.origin.y, 5, rect.size.height); CGContextSaveGState(context); CGContextSetShadowWithColor(context, CGSizeMake(-5, 0), 5, [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor); CGContextSetFillColorWithColor(context, [UIColor networkingColor].CGColor); CGContextFillRect(context, rectLeft); CGContextRestoreGState(context); // re-draw the background CGContextSetFillColorWithColor(context, backgroundColor.CGColor); CGContextFillRect(context, rect); CGContextSaveGState(context); UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(4.0, 4.0)]; [maskPath addClip]; CGContextSetFillColorWithColor(context, fillColor.CGColor); CGContextFillRect(context, rect); CGContextRestoreGState(context); 

HTH

En muchos casos, querrías lograr esto dibujando la sombra, por supuesto. Sin embargo, puede considerar el siguiente enfoque: usar una image estirable con la sombra justo en los lados que necesita, por ejemplo, algo similar a (aunque tiene sombra en todos los lados):

introduzca la descripción de la imagen aquí

Justo antes de decir: " ¡Ewwwww! ¡Está usando una image para una simple sombra! ", Permítanme enfatizar que esto funcionará mucho mejor en términos de performance. Por ejemplo, si tiene muchas celdas en una UICollectionView y cada una está volviendo a dibujar su sombra, podría ralentizar significativamente su aplicación durante el desplazamiento, mientras que con una sombra basada en imágenes será esencialmente la misma.

¡Iré aún más lejos y sugiero que realmente puedas usar una image estirable para enmascarar la vista con esquinas networkingondeadas también ! Ahora, esto puede parecer ir un poco demasiado lejos, pero si nota una disminución drástica en el performance, lo daría una oportunidad. Lo que esencialmente debe hacer es preparar otra image estirable con una parte transparente "media" y esquinas networkingondeadas del mismo color que su background. Algo como:

introduzca la descripción de la imagen aquí

Y una vez más, antes de descartar esta forma extraña de hacer algo que se puede lograr fácilmente con dos líneas de código …

 view.layer.cornerRadius = 20 view.layer.masksToBounds = true 

… Permítanme señalar que esto funcionará ridículamente más rápido en los casos en que tenga que mostrar un grupo de esas vistas enmascaradas simultáneamente: por ejemplo, enmascarar UICollectionViewCell s. Básicamente, si configura una máscara en la capa de UIView , esta máscara se volverá a calcular y aplicará en time real, lo que le costaría mucho en términos de performance durante el networkingibujado frecuente de los contenidos de UIView – al desplazarse por un UITableView o UICollectionView , por ejemplo.

Obviamente, esto no funcionaría si su background no es de un color sólido, y tiene un gradiente, por ejemplo. Sin embargo, en muchos otros casos esto puede ayudarlo a lograr un performance mucho más suave de la interfaz de usuario. Otra ventaja en su caso particular es que puede controlar fácilmente qué esquinas enmascarar y dónde debe caer la sombra.

Nuevamente, no estoy dando a entender que este es el path a seguir en todos y cada uno de los casos . Lo que estoy diciendo es que hay muchos casos en que esto podría ayudar a boost el performance de manera significativa: por ejemplo, si está enmascarando demasiadas vistas que se muestran en la pantalla al mismo time, y se espera que el layout para ser networkingiseñado con frecuencia.

para el radio de la esquina del set de esquina específico

consulte: cómo configurar cornerRadius solo para la esquina superior izquierda y superior derecha de una UIView?

 UIBezierPath *maskPath; maskPath = [UIBezierPathbezierPathWithRoundedRect:_backgroundImageView.bounds byRoundingCorners:(UIRectCornerBottomLeft|UIRectCornerBottomRight) cornerRadii:CGSizeMake(3.0, 3.0)]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; maskLayer.frame = self.bounds; maskLayer.path = maskPath.CGPath; _imageView.layer.mask = maskLayer; [maskLayer release];