2011-01-19 10 views
29

¿Alguien tiene alguna experiencia en aplicar un degradado a un CAShapeLayer? CAShapeLayer es una fantástica clase de capa, pero parece que solo admite colores de relleno sólidos, mientras que me gustaría que tuviera un relleno de degradado (en realidad, un degradado animable).Aplicar un degradado a CAShapeLayer

Todo lo demás que ver con CAShapeLayer (sombras, formas, color del trazo, trazado de forma animatable) es fantástico.

He intentado colocar un CAGradientLayer dentro de un CAShapeLayer, o de hecho estableciendo CAShapeLayer como la máscara de GradientLayer y agregando ambos a una capa de contenedor, pero estos no tienen el resultado correcto.

¿Debo subclase CAShapeLayer, o hay una mejor manera hacia adelante?

Gracias.

+0

Creo que [esta cuestión] (http://stackoverflow.com/questions/1303855/how-to-draw-a-gradient-line-fading-in-out-with-core-graphics-iphone) contiene la [respuesta de Matt Long] (http://stackoverflow.com/questions/1303855/how-to-draw-a-gradient-line-fading-in-out-with-core-graphics-iphone/1303943# 1303943). – Palimondo

Respuesta

53

Usted podría utilizar la ruta de su forma para crear una capa de máscara y aplicar que en la capa de degradación, así:

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

Si desea utilizar también las sombras, se tendría que colocar una "duplicar" la capa de forma debajo de la capa de degradado, reciclando la misma referencia de ruta.

+2

Esta es una respuesta increíble. Para aquellos que no conscientes de esta (como yo), me gustaría añadir que se puede añadir la máscara, gradiente, sombra y cualesquiera otras capas puede que necesite una capa de contenedores ('recipiente CALayer = [capa CALayer] ') y luego solo tiene que administrar esa capa de contenedor si necesita animar su posición. –

+0

¡Gran respuesta! ¡Gracias! – user5685969

2

Esta es una gran solución, pero es posible encontrar problemas inesperados si va a crear una categoría en CAShapeLayer en el que no tiene de inmediato la vista.

Ver Setting correct frame of a newly created CAShapeLayer

En pocas palabras, consiguen los límites de la trayectoria a continuación, establezca el marco de la máscara de degradado usando los límites de trayectoria y traducir como sea necesario. Lo bueno aquí es que al usar los límites de la ruta en lugar de cualquier otro marco, el degradado solo se ajustará dentro de los límites de la ruta (suponiendo que eso es lo que desea).

// 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]; 
Cuestiones relacionadas