2011-01-19 13 views
29

Qualcuno ha esperienza nell'applicare un gradiente a un CAShapeLayer? CAShapeLayer è una fantastica classe di livelli, ma sembra supportare solo la colorazione a riempimento solido, mentre mi piacerebbe che avesse un riempimento sfumato (in realtà un gradiente animabile).Applicazione di un gradiente a CAShapeLayer

Tutto il resto da fare con CAShapeLayer (ombre, forme, colore del tratto, percorso forma animabile) è fantastico.

Ho provato a collocare un CAGradientLayer all'interno di un CAShapeLayer, o addirittura a impostare CAShapeLayer come maschera del GradientLayer e ad aggiungerlo a un livello contenitore, ma questi non hanno il risultato corretto.

Devo eseguire la sottoclasse di CAShapeLayer oppure esiste una soluzione migliore?

Grazie.

+0

Credo che [questa domanda] (http://stackoverflow.com/questions/1303855/how-to-draw-a-gradient-line-fading-in-out-with-core-graphics-iphone) contiene la [risposta di Matt Long] (http://stackoverflow.com/questions/1303855/how-to-draw-a-gradient-line-fading-in-out-with-core-graphics-iphone/1303943# 1.303.943). – Palimondo

risposta

53

Si potrebbe utilizzare il percorso della forma per creare uno strato di mascheratura e applicare quello sul livello della sfumatura, come questo:

UIView *v = [[UIView alloc] initWithFrame:self.window.frame]; 

CAShapeLayer *gradientMask = [CAShapeLayer layer]; 
gradientMask.fillColor = [[UIColor clearColor] CGColor]; 
gradientMask.strokeColor = [[UIColor blackColor] CGColor]; 
gradientMask.lineWidth = 4; 
gradientMask.frame = CGRectMake(0, 0, v.bounds.size.width, v.bounds.size.height); 

CGMutablePathRef t = CGPathCreateMutable();  
CGPathMoveToPoint(t, NULL, 0, 0); 
CGPathAddLineToPoint(t, NULL, v.bounds.size.width, v.bounds.size.height); 

gradientMask.path = t; 


CAGradientLayer *gradientLayer = [CAGradientLayer layer]; 
gradientLayer.startPoint = CGPointMake(0.5,1.0); 
gradientLayer.endPoint = CGPointMake(0.5,0.0); 
gradientLayer.frame = CGRectMake(0, 0, v.bounds.size.width, v.bounds.size.height); 
NSMutableArray *colors = [NSMutableArray array]; 
for (int i = 0; i < 10; i++) { 
    [colors addObject:(id)[[UIColor colorWithHue:(0.1 * i) saturation:1 brightness:.8 alpha:1] CGColor]]; 
} 
gradientLayer.colors = colors; 

[gradientLayer setMask:gradientMask]; 
[v.layer addSublayer:gradientLayer]; 

Se si desidera utilizzare anche le ombre, si dovrebbe mettere un "duplicato" del livello forma sotto il livello sfumatura, riciclando lo stesso riferimento di percorso.

+2

Questa è una risposta sorprendente. Per coloro che non ne sono a conoscenza (come lo ero io), vorrei aggiungere che è possibile aggiungere la maschera, il gradiente, l'ombra e qualsiasi altro livello necessario a un livello Contenitore ('Contenitore CALayer = [Livello CALayer] ') e quindi è sufficiente gestire quel livello contenitore se è necessario animare la sua posizione. –

+0

Ottima risposta! Grazie! – user5685969

2

Questa è un'ottima soluzione, ma potresti incontrare problemi imprevisti se stai creando una categoria su CAShapeLayer in cui non hai immediatamente la vista.

Vedi Setting correct frame of a newly created CAShapeLayer

riassumere, ottenere i limiti del percorso quindi impostare telaio della maschera gradiente utilizzando i limiti di percorso e tradurre come necessario. La cosa buona è che usando i limiti del percorso piuttosto che qualsiasi altro frame, il gradiente si adatterà solo all'interno dei limiti del percorso (assumendo che sia ciò che si desidera).

// Category on CAShapeLayer 

CGRect pathBounds = CGPathGetBoundingBox(self.path); 

CAShapeLayer *gradientMask = [CAShapeLayer layer]; 
gradientMask.fillColor = [[UIColor blackColor] CGColor]; 
gradientMask.frame = CGRectMake(0, 0, pathBounds.size.width, pathBounds.size.height); 
gradientMask.path = self.path; 

CAGradientLayer *gradientLayer = [CAGradientLayer layer]; 
gradientLayer.startPoint = CGPointMake(0.5,1.0); 
gradientLayer.endPoint = CGPointMake(0.5,0.0); 
gradientLayer.frame = CGRectMake(0, 0, pathBounds.size.width, pathBounds.size.height); 

NSMutableArray *colors = [NSMutableArray array]; 
for (int i = 0; i < 10; i++) { 
    [colors addObject:(id)[[UIColor colorWithHue:(0.1 * i) saturation:1 brightness:.8 alpha:1] CGColor]]; 
} 
gradientLayer.colors = colors; 

[gradientLayer setMask:gradientMask]; 
[self addSublayer:gradientLayer]; 
Problemi correlati