如何清除CATextLayer中的文本

时间:2010-09-28 17:29:39

标签: text ios core-animation calayer

我添加了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。

7 个答案:

答案 0 :(得分:218)

简短回答 - 您需要设置内容缩放:

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

前段时间我了解到,当您拥有自定义绘图代码时,您必须检查视网膜显示并相应地缩放图形。 UIKit负责处理大部分内容,包括字体缩放。

CATextLayer.

不是这样

我的模糊来自于.zPosition不是零,也就是说,我将变换应用于我的父图层。通过将其设置为零,模糊性消失了,并被严重的像素化所取代。

搜索高低后,我发现您可以为.contentsScale设置CATextLayer,然后将其设置为[[UIScreen mainScreen] scale]以匹配屏幕分辨率。 (我认为这适用于非视网膜,但我没有检查 - 太累了)

在我的CATextLayer中包含此内容后,文字变得清晰。注意 - 父层不需要。

模糊不清?当你在3D中旋转时它会回来,但是你没有注意到它,因为文本开始时是清晰的,当它处于运动状态时,你无法分辨。

问题解决了!

答案 1 :(得分:31)

夫特

将文本图层设置为与屏幕使用相同的比例。

textLayer.contentsScale = UIScreen.main.scale

之前:

enter image description here

后:

enter image description here

答案 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. 设置要进行栅格化的基础图层的rasterizationScale
  2. 设置任何CATextLayers的contentScale属性以及可能的其他类型的图层(它永远不会伤害它)
  3. 如果你不做#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];