2011-12-13 15 views
6

Tengo una colección de CALayers. Cada capa es una subcapa del mismo padre CALayer, y cada una tiene una sombra aplicada a ella. Las capas están posicionadas dinámicamente, y hay muchas de ellas, por lo que no puedo predecir cómo se organizarán antes de tiempo.¿Hay alguna forma de evitar que las sombras de CALayer se superpongan a capas adyacentes?

Si las capas son adyacentes entre sí (lo suficientemente cerca que son casi tocando) la sombra de uno de los CALayers se representa en la parte superior de la otra CALayer. Ese es probablemente el efecto deseado en la mayoría de los casos, pero quiero que mis capas existan en el mismo plano z. (Un ejemplo de esto es la manera en que se aplican las sombras CSS3 a los elementos del bloque en el diseño web.)

¿Esto es posible? ¿Cómo puedo conseguir esto?

(Tuve esta idea: Agregar una subcapa 'sombra' a cada CALayer con mi propia imagen de sombra y establecer la posición z a un valor inferior. ¿Pero el árbol de capas no lo hace imposible? las posiciones en el sistema de coordenadas de una capa son independientes de las posiciones z en el sistema de coordenadas de otra capa, ¿no?)

Respuesta

16

Si todas las capas sombreadas tienen la misma configuración de sombreado, colóquelas en una capa de contenedor y configure la sombra en el contenedor capa. Ejemplo:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    CALayer *containerLayer = [CALayer layer]; 
    containerLayer.frame = self.view.bounds; 
    containerLayer.shadowRadius = 10; 
    containerLayer.shadowOpacity = 1; 
    [self.view.layer addSublayer:containerLayer]; 

    CAShapeLayer *layer1 = [CAShapeLayer layer]; 
    layer1.bounds = CGRectMake(0, 0, 200, 200); 
    layer1.position = CGPointMake(130, 130); 
    layer1.path = [UIBezierPath bezierPathWithOvalInRect:layer1.bounds].CGPath; 
    layer1.fillColor = [UIColor redColor].CGColor; 
    [containerLayer addSublayer:layer1]; 

    CAShapeLayer *layer2 = [CAShapeLayer layer]; 
    layer2.bounds = CGRectMake(0, 0, 200, 200); 
    layer2.position = CGPointMake(170, 200); 
    layer2.path = [UIBezierPath bezierPathWithOvalInRect:layer2.bounds].CGPath; 
    layer2.fillColor = [UIColor blueColor].CGColor; 
    [containerLayer addSublayer:layer2]; 
} 

Salida:

overlapping circles with unified shadow

+0

Wow, gracias! Esto es tan obvio en retrospectiva. La idea se me ocurrió, pero pensé que habría aplicado una sombra a la forma de la capa del contenedor (lo que sea, jaja). –

+1

+1 Excelente respuesta – occulus

Cuestiones relacionadas