Cómo conseguir que el text en un CATextLayer sea claro

Hice un CALayer con un añadido CATextLayer y el text sale borroso. En los documentos, hablan de "antialiasing sub-pixel", pero eso no significa mucho para mí. ¿Alguien tiene un fragment de código que hace que un CATextLayer con un poco de text sea claro?

Aquí está el text de la documentation de Apple:

Nota: CATextLayer deshabilita el antialiasing sub-pixel al representar text. El text solo se puede dibujar utilizando antialias de subpíxel cuando está compuesto en un background opaco existente al mismo time que se rasteriza. No hay forma de dibujar text con subpixel-antialiased por sí mismo, ya sea en una image o una capa, por separado antes de tener los píxeles de background para entretejer los píxeles de text. Establecer la propiedad de opacidad de la capa en YES no cambia el modo de representación.

La segunda oración implica que uno puede get un text atractivo si se lo composites en un existing opaque background at the same time that it's rasterized. Eso es genial, pero ¿cómo lo compuse y cómo le das un background opaco y cómo lo rasterizas?

El código que usan en su ejemplo de un menu de quiosco es como tal: (es OS X, no iOS, pero supongo que funciona).

 NSInteger i; for (i=0;i<[names count];i++) { CATextLayer *menuItemLayer=[CATextLayer layer]; menuItemLayer.string=[self.names objectAtIndex:i]; menuItemLayer.font=@"Lucida-Grande"; menuItemLayer.fontSize=fontSize; menuItemLayer.foregroundColor=whiteColor; [menuItemLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxY relativeTo:@"superlayer" attribute:kCAConstraintMaxY offset:-(i*height+spacing+initialOffset)]]; [menuItemLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidX relativeTo:@"superlayer" attribute:kCAConstraintMidX]]; [self.menuLayer addSublayer:menuItemLayer]; } // end of for loop 

¡Gracias!


EDITAR: Agregar el código que realmente utilicé resultó en text borroso. Es a partir de una pregunta relacionada que UILabel sobre la adición de un UILabel lugar de un CATextLayer pero CATextLayer un cuadro negro en su lugar. http://stackoverflow.com/questions/3818676/adding-a-uilabels-layer-to-a-calayer-and-it-just-shows-black-box

 CATextLayer* upperOperator = [[CATextLayer alloc] init]; CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); CGFloat components1[4] = {1.0, 1.0, 1.0, 1.0}; CGColorRef almostWhite = CGColorCreate(space,components1); CGFloat components2[4] = {0.0, 0.0, 0.0, 1.0}; CGColorRef almostBlack = CGColorCreate(space,components2); CGColorSpaceRelease(space); upperOperator.string = [NSString stringWithFormat:@"13"]; upperOperator.bounds = CGRectMake(0, 0, 100, 50); upperOperator.foregroundColor = almostBlack; upperOperator.backgroundColor = almostWhite; upperOperator.position = CGPointMake(50.0, 25.0); upperOperator.font = @"Helvetica-Bold"; upperOperator.fontSize = 48.0f; upperOperator.borderColor = [UIColor networkingColor].CGColor; upperOperator.borderWidth = 1; upperOperator.alignmentMode = kCAAlignmentCenter; [card addSublayer:upperOperator]; [upperOperator release]; CGColorRelease(almostWhite); CGColorRelease(almostBlack); 

EDIT 2: Vea mi respuesta a continuación para ver cómo se resolvió esto. sbg

Respuesta corta: necesita configurar la escala de contenido:

 textLayer.contentsScale = [[UIScreen mainScreen] scale]; 

Hace un time aprendí que cuando tienes un código de dibujo personalizado, debes verificar la visualización de la retina y escalar los charts de acuerdo con esto. UIKit se encarga de la mayor parte de esto, incluido el escalado de fonts.

No es así con CATextLayer.

Mi visión borrosa vino de tener una position .zPosition que no era cero, es decir, tenía una transformación aplicada a mi capa primaria. Al ajustar esto a cero, la borrosidad desapareció y fue reemplazada por una gran pixelación.

Después de search alta y baja, encontré que puede configurar .contentsScale para un CATextLayer y puede configurarlo en [[UIScreen mainScreen] scale] para que coincida con la resolución de pantalla. (Supongo que esto funciona para la no retina, pero no lo he comprobado, demasiado cansado)

Después de include esto para mi CATextLayer el text se volvió nítido. Nota: no es necesario para la capa principal.

¿Y la borrosidad? Regresa cuando giras en 3D, pero no te das count porque el text comienza a despejarse y mientras está en movimiento, no puedes decirlo.

¡Problema resuelto!

En primer lugar, quise señalar que has labeldo tu pregunta con iOS, pero los administradores de restricciones solo están disponibles en OSX, así que no estoy seguro de cómo funciona esto a less que hayas podido vincularlo en el simulador de alguna manera. En el dispositivo, esta funcionalidad no está disponible.

A continuación, solo señalaré que creo CATextLayers a menudo y nunca tengo el problema borroso al que te refieres, así que sé que se puede hacer. En pocas palabras, esta borrosidad se produce porque no está posicionando su capa en todo el píxel. Recuerde que cuando establece la position de una capa, usa valores flotantes para xey. Si esos valores tienen numbers después del decimal, la capa no se colocará en todo el píxel y, por lo tanto, dará este efecto de desenfoque, el grado de que dependerá de los valores reales. Para probar esto, simplemente cree un CATextLayer y agréguelo explícitamente al tree de capas asegurándose de que su parámetro de position esté en un píxel integer. Por ejemplo:

 CATextLayer *textLayer = [CATextLayer layer]; [textLayer setBounds:CGRectMake(0.0f, 0.0f, 200.0f, 30.0f)]; [textLayer setPosition:CGPointMake(200.0f, 100.0f)]; [textLayer setString:@"Hello World!"]; [[self menuLayer] addSublayer:textLayer]; 

Si tu text todavía está borroso, entonces hay algo más mal. El text borroso en la capa de text es un artefacto de código escrito incorrectamente y no una capacidad prevista de la capa. Cuando agregue sus capas a una capa primaria, simplemente puede obligar a los valores x e y al píxel integer más cercano y debería resolver su problema de desenfoque.

Atentamente.

Antes de configurar shouldRasterize, debe:

  1. establezca la escala de rasterización de la capa base que va a rasterizar
  2. establezca la propiedad contentsScale de cualquier CATextLayers y posiblemente otros types de capas (nunca está de más hacerlo)

Si no hace el número 1, la versión de retina de las subcapas se verá borrosa, incluso para los CALayers normales.

 - (void)viewDidLoad { [super viewDidLoad]; CALayer *mainLayer = [[self view] layer]; [mainLayer setRasterizationScale:[[UIScreen mainScreen] scale]]; CATextLayer *messageLayer = [CATextLayer layer]; [messageLayer setForegroundColor:[[UIColor blackColor] CGColor]]; [messageLayer setContentsScale:[[UIScreen mainScreen] scale]]; [messageLayer setFrame:CGRectMake(50, 170, 250, 50)]; [messageLayer setString:(id)@"asdfasd"]; [mainLayer addSublayer:messageLayer]; [mainLayer setShouldRasterize:YES]; } 

Establezca la capa de text para usar la misma escala que la pantalla.

 textLayer.contentsScale = UIScreen.main.scale 

Antes de:

introduzca la descripción de la imagen aquí

Después:

introduzca la descripción de la imagen aquí

Deberías hacer 2 cosas, la primera fue mencionada anteriormente:

Extienda CATextLayer y establezca las properties opacas y contentScale para admitir correctamente la visualización de la retina, luego renderice con anti alias habilitado para el text.

 + (TextActionLayer*) layer { TextActionLayer *layer = [[TextActionLayer alloc] init]; layer.opaque = TRUE; CGFloat scale = [[UIScreen mainScreen] scale]; layer.contentsScale = scale; return [layer autorelease]; } // Render after enabling with anti aliasing for text - (void)drawInContext:(CGContextRef)ctx { CGRect bounds = self.bounds; CGContextSetFillColorWithColor(ctx, self.backgroundColor); CGContextFillRect(ctx, bounds); CGContextSetShouldSmoothFonts(ctx, TRUE); [super drawInContext:ctx]; } 

Si viniste a search aquí un problema similar para un CATextLayer en OSX, después de mucho golpear la cabeza de la panetworking, obtuve el text nítido y claro haciendo:

 text_layer.contentsScale = self.window!.backingScaleFactor 

(También establezco que las vistas de la capa de background contentsScale sean iguales).

Esto es más rápido y más fácil: solo tiene que configurar contenidos Scale

  CATextLayer *label = [[CATextLayer alloc] init]; [label setFontSize:15]; [label setContentsScale:[[UIScreen mainScreen] scale]]; [label setFrame:CGRectMake(0, 0, 50, 50)]; [label setString:@"test"]; [label setAlignmentMode:kCAAlignmentCenter]; [label setBackgroundColor:[[UIColor clearColor] CGColor]]; [label setForegroundColor:[[UIColor blackColor] CGColor]]; [self addSublayer:label];