2010-02-05 15 views

Respuesta

37

No creo que pueda agregar una subclase UIView a un objeto CALayer. Sin embargo, si desea dibujar texto en un objeto CALayer, puede hacerlo utilizando las funciones de dibujo provistas en NSString UIKit additions como se muestra a continuación. Mientras mi código se hace en el método drawLayer: inContext del delegado, lo mismo se puede usar en la subclase 'drawInContext: method. ¿Hay alguna funcionalidad UILabel específica que desee aprovechar?

- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx { 
    CGContextSetFillColorWithColor(ctx, [[UIColor darkTextColor] CGColor]); 

    UIGraphicsPushContext(ctx); 
    /*[word drawInRect:layer.bounds 
      withFont:[UIFont systemFontOfSize:32] 
    lineBreakMode:UILineBreakModeWordWrap 
     alignment:UITextAlignmentCenter];*/ 

    [word drawAtPoint:CGPointMake(30.0f, 30.0f) 
      forWidth:200.0f 
      withFont:[UIFont boldSystemFontOfSize:32] 
     lineBreakMode:UILineBreakModeClip]; 

    UIGraphicsPopContext(); 
} 
+0

[[UIColor darkTextColor] establecer] también funciona cuando el contexto gráfico ha sido empujado – rpetrich

+0

@ Deepak Danduprolu Esto funciona para mí, pero deambulo por qué debería llamar a la función push y pop para que funcione – zeroleaf

4

Su UILabel ya tiene un CALayer detrás de él. Si está reuniendo varios CALayers, puede simplemente agregar la capa de UILabel como una subcapa de uno de ellos (mediante el uso de su propiedad layer).

Si es un dibujo de texto directo en la capa que desea, las adiciones de UIKit NSString señaladas por Deepak son el camino a seguir. Para obtener un ejemplo de esto en acción, el Core Plot framework tiene una subclase CALayer independiente de la plataforma Mac/iPhone que realiza el procesamiento de texto, CPTextLayer.

+0

Hey Brad, de hecho solía usar esta técnica (agregando una capa de UILabel a un CALayer) y parece que tal vez ha dejado de funcionar en el iOS 8 base SDK? Empecé a reconstruir una aplicación antigua que creé y que exporta videos, y las subcapas del CALayer padre parecen permanecer nulas con este código anterior. Podría ser otra cosa incorrecta, seguir buscando. –

+0

Solucionado. Para cualquier otra persona que venga a buscar cómo hacer este trabajo compilado contra iOS 8 Base SDK, llame a [label.layer display] antes de agregar la capa de la etiqueta a otro CALayer. Crédito: http://stackoverflow.com/questions/23171790/is-it-safe-to-add-a-stolen-uilabels-layer-to-some-other-calayers-sublayer –

2

Agregue un CATextLayer como una subcapa y establezca la propiedad de cadena. Eso sería más fácil y puede usar fácilmente un administrador de diseño para hacerlo muy genérico.

+2

... _puede usar fácilmente un diseño manager _... Bueno, en MacOS, sí, pero no en iOS. Los CALayers en iOS no son compatibles con los administradores de diseño: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/Layout.html – Dalbergia

+0

¡No lo sabía! Gracias amigo –

135
 CATextLayer *label = [[CATextLayer alloc] init]; 
     [label setFont:@"Helvetica-Bold"]; 
     [label setFontSize:20]; 
     [label setFrame:validFrame]; 
     [label setString:@"Hello"]; 
     [label setAlignmentMode:kCAAlignmentCenter]; 
     [label setForegroundColor:[[UIColor whiteColor] CGColor]]; 
     [layer addSublayer:label]; 

     [label release]; 
+3

En mi humilde opinión, esta es una solución más simple que un CALayer personalizado o un delegado de capa, siempre y cuando no necesite más que un simple dibujo de texto. CATextLayer ya sabe cómo dibujar texto, por lo que no es necesario reinventar la rueda. – Dalbergia

+0

@ Mshah2 ¿por qué el texto viene con un efecto no antialiasing? el texto se ve como si hubiera sido aumentado – sreekanthk

+16

. Necesita ajustar la escala de contenido del CALayer; de lo contrario, obtendrá un texto borroso en los dispositivos retina (@ 2x) o @ 3x. Uso: label.contentsScale = [UIScreen mainScreen] .scale; – yonel

-1

Recuerde siempre quitar subcapas anteriores, si se va a añadir otro, para evitar puntos de vista que duplican:

if let sublayers = layer.sublayers { 
    for sublayer in sublayers { 
     sublayer.removeFromSuperlayer() 
    } 
}