我添加了CALayer
CATextLayer
,文字模糊不清。在文档中,他们谈论“亚像素抗锯齿”,但这对我来说并不重要。任何人都有一个代码段,使CATextLayer
的文字清晰明了吗?
以下是Apple文档中的文字:
注意:CATextLayer在渲染文本时禁用子像素抗锯齿。 文本只能使用子像素抗锯齿来绘制 同时合成到现有的不透明背景中 它是栅格化的。没有办法绘制亚像素抗锯齿文本 本身,无论是图像还是图层,分别提前 具有背景像素以编织文本像素。设置 图层的opacity属性为YES不会更改渲染 模式。
第二句意味着如果一个composites
成为existing opaque background at the same time that it's rasterized.
,那么可以获得好看的文字那很好,但我如何合成它以及如何给它一个不透明的背景呢?你光栅化了吗?
他们在Kiosk菜单示例中使用的代码是这样的:(它是OS X,而不是iOS,但我认为它有效!)
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
谢谢!
编辑:添加我实际使用的代码会导致文本模糊。这是我发布的有关添加UILabel
而不是CATextLayer
的相关问题,而是改为使用黑匣子。 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);
编辑2:请参阅下面的答案,了解这是如何解决的。 SBG。
答案 0 :(得分:218)
简短回答 - 您需要设置内容缩放:
textLayer.contentsScale = [[UIScreen mainScreen] scale];
前段时间我了解到,当您拥有自定义绘图代码时,您必须检查视网膜显示并相应地缩放图形。 UIKit
负责处理大部分内容,包括字体缩放。
CATextLayer.
我的模糊来自于.zPosition
不是零,也就是说,我将变换应用于我的父图层。通过将其设置为零,模糊性消失了,并被严重的像素化所取代。
搜索高低后,我发现您可以为.contentsScale
设置CATextLayer
,然后将其设置为[[UIScreen mainScreen] scale]
以匹配屏幕分辨率。 (我认为这适用于非视网膜,但我没有检查 - 太累了)
在我的CATextLayer
中包含此内容后,文字变得清晰。注意 - 父层不需要。
模糊不清?当你在3D中旋转时它会回来,但是你没有注意到它,因为文本开始时是清晰的,当它处于运动状态时,你无法分辨。
问题解决了!
答案 1 :(得分:31)
答案 2 :(得分:17)
首先,我想指出你已经用iOS标记了你的问题,但约束管理器只能在OSX上使用,所以我不确定你是如何让这个工作的,除非你能够以某种方式在模拟器中链接它。在设备上,此功能不可用。
接下来,我将指出我经常创建CATextLayers并且从未遇到过您所指的模糊问题,因此我知道可以完成。简而言之,这种模糊的发生是因为您没有将图层放在整个像素上。请记住,在设置图层的位置时,可以使用x和y的浮点值。如果这些值在小数点后面有数字,则图层将不会定位在整个像素上,因此会产生这种模糊效果 - 其程度取决于实际值。要对此进行测试,只需创建一个CATextLayer并将其显式添加到图层树中,以确保您的位置参数位于整个像素上。例如:
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];
如果您的文字仍然模糊,那么还有其他问题。文本图层上的模糊文本是错误编写代码的工件,而不是图层的预期功能。将图层添加到父图层时,您可以将x和y值强制转换为最接近的整个像素,这样可以解决模糊问题。
答案 3 :(得分:14)
在设置shouldRasterize之前,您应该:
如果你不做#1,那么子图层的视网膜版本看起来会很模糊,即使对于普通的CALayers也是如此。
- (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];
}
答案 4 :(得分:4)
你应该做两件事,第一件事是上面提到的:
扩展CATextLayer并设置opaque和contentsScale属性以正确支持视网膜显示,然后为文本启用抗锯齿渲染。
+ (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];
}
答案 5 :(得分:2)
如果你在这里搜索OSX中CATextLayer的类似问题,经过多次敲门打击后,我得到了清晰的文字:
text_layer.contentsScale = self.window!.backingScaleFactor
(我还将视图背景图层contentsScale设置为相同)。
答案 6 :(得分:0)
这更快更容易:您只需要设置contentsScale
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];