Hice un CALayer
con un agregado CATextLayer
y el texto sale borroso. En los documentos, se habla de "suavizado de subpíxeles", pero eso no significa mucho para mí. ¿Alguien tiene un fragmento de código que haga una CATextLayer
con un poco de texto que sea claro?
Aquí está el texto de la documentación de Apple:
Nota: CATextLayer deshabilita el suavizado de subpíxeles al representar texto. El texto solo se puede dibujar usando suavizado de subpíxeles cuando se compone en un fondo opaco existente al mismo tiempo que se rasteriza. No hay forma de dibujar texto con suavizado de subpíxeles por sí mismo, ya sea en una imagen o una capa, por separado antes de tener los píxeles de fondo para entretejer los píxeles de texto. Establecer la propiedad de opacidad de la capa en SÍ no cambia el modo de renderizado.
La segunda oración implica que uno puede obtener un texto atractivo si uno composites
lo convierte en un existing opaque background at the same time that it's rasterized.
Eso es genial, pero ¿cómo lo compongo y cómo le da un fondo opaco y cómo lo rasteriza?
El código que usan en su ejemplo de un menú 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 usé que resultó en texto borroso. Es de una pregunta relacionada que publiqué sobre agregar un en UILabel
lugar de un, CATextLayer
pero obtener una caja negra 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 redColor].CGColor;
upperOperator.borderWidth = 1;
upperOperator.alignmentMode = kCAAlignmentCenter;
[card addSublayer:upperOperator];
[upperOperator release];
CGColorRelease(almostWhite);
CGColorRelease(almostBlack);
EDITAR 2: Vea mi respuesta a continuación para saber cómo se resolvió esto. sbg.
fuente
Respuestas:
Respuesta corta: debe configurar la escala de contenido:
Hace un tiempo aprendí que cuando tienes un código de dibujo personalizado, debes verificar la pantalla de retina y escalar tus gráficos en consecuencia.
UIKit
se encarga de la mayor parte de esto, incluida la escala de fuentes.No es así con
CATextLayer.
Mi borrosidad vino de tener un
.zPosition
que no era cero, es decir, tenía una transformación aplicada a mi capa principal. Al establecer esto en cero, la borrosidad desapareció y fue reemplazada por una pixelación seria.Después de buscar alto y bajo, descubrí que puede configurar
.contentsScale
aCATextLayer
y puede configurarlo[[UIScreen mainScreen] scale]
que coincida con la resolución de la pantalla. (Supongo que esto funciona para no retina, pero no lo he comprobado, demasiado cansado)Después de incluir esto para mi
CATextLayer
el texto se volvió nítido. Nota: no es necesario para la capa principal.¿Y la borrosidad? Vuelve cuando estás rotando en 3D, pero no lo notas porque el texto comienza claro y mientras está en movimiento, no puedes saberlo.
¡Problema resuelto!
fuente
textLayer.contentScale = [[UIScreen mainScreen] scale];
Por cierto, a mí también me gustan las respuestas largas :)_textLayer.contentsScale = [[UIScreen mainScreen] scale];
Falta una "s";)Rápido
Configure la capa de texto para usar la misma escala que la pantalla.
Antes de:
Después:
fuente
En primer lugar, quería señalar que ha etiquetado su pregunta con iOS, pero los administradores de restricciones solo están disponibles en OSX, por lo que no estoy seguro de cómo está logrando que esto funcione a menos que haya 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 con frecuencia y nunca tengo el problema de desenfoque al que se refiere, así que sé que se puede hacer. En pocas palabras, este desenfoque se produce porque no está colocando su capa en todo el píxel. Recuerde que cuando establece la posición de una capa, usa valores flotantes para x e y. Si esos valores tienen números después del decimal, la capa no se colocará en todo el píxel y, por lo tanto, dará este efecto de desenfoque, cuyo grado dependerá de los valores reales. Para probar esto, simplemente cree un CATextLayer y agréguelo explícitamente al árbol de capas, asegurándose de que su parámetro de posición esté en un píxel completo. Por ejemplo:
Si su texto aún está borroso, entonces hay algo más mal. El texto borroso en su capa de texto es un artefacto de código escrito incorrectamente y no una capacidad prevista de la capa. Al agregar sus capas a una capa principal, puede simplemente forzar los valores xey al píxel completo más cercano y debería resolver su problema de desenfoque.
fuente
Antes de configurar shouldRasterize, debe:
Si no hace el n. ° 1, la versión retina de las subcapas se verá borrosa, incluso para los CALayers normales.
fuente
Debes hacer 2 cosas, la primera se mencionó anteriormente:
Extienda CATextLayer y establezca las propiedades opaco y contentsScale para admitir correctamente la visualización de retina, luego renderice con el suavizado habilitado para el texto.
fuente
Si vino a buscar aquí un problema similar para un CATextLayer en OSX, después de muchos golpes en la pared, obtuve el texto claro y nítido haciendo:
(También configuré el contenido de la capa de fondo de las vistas Escala para que sea el mismo).
fuente
Esto es más rápido y más fácil: solo necesita configurar el contenido
fuente