2011-12-13 10 views
6

Ho una collezione di CALayers. Ogni livello è un sottolivello dello stesso genitore CALayer e ad ognuno viene applicata un'ombreggiatura. Gli strati sono posizionati dinamicamente, e ce ne sono molti, quindi non posso prevedere come saranno disposti in anticipo.C'è un modo per evitare che le ombre di CALayer si sovrappongano ai livelli adiacenti?

Se gli strati sono adiacenti l'uno all'altro (abbastanza vicini da essere quasi a contatto) l'ombra di uno degli CALayers viene visualizzata sopra l'altro CALayer. Probabilmente è l'effetto desiderato nella maggior parte dei casi, ma voglio che i miei livelli esistano nello stesso piano z. (Un esempio di questo è il modo in cui le ombre CSS3 vengono applicate agli elementi di blocco nel web design.)

È possibile? Come posso raggiungere questo obiettivo?

(mi è venuta questa idea: aggiungere un sottolivello "ombra" a ciascuna CALayer con la mia immagine ombreggiata e impostare la posizione z su un valore inferiore. Ma l'albero dei livelli non lo rende impossibile? le posizioni nel sistema di coordinate di un livello sono indipendenti dalle posizioni z del sistema di coordinate di un altro livello, giusto?)

risposta

16

Se tutti i livelli in ombra hanno le stesse impostazioni di ombreggiatura, inserirli in un livello contenitore e impostare l'ombra sul contenitore strato. Esempio:

- (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]; 
} 

uscita:

overlapping circles with unified shadow

+0

Wow, grazie! Questo è così ovvio col senno di poi. L'idea mi è venuta in mente, ma ho pensato che avrebbe applicato un'ombra alla forma del livello contenitore (qualunque cosa sia, haha). –

+1

+1 Risposta eccellente – occulus

Problemi correlati