Я сделал CALayer
с добавлением, CATextLayer
и текст получается размытым. В документации говорится о «субпиксельном сглаживании», но для меня это мало что значит. У кого-нибудь есть фрагмент кода, который делает CATextLayer
небольшой текст понятным?
Вот текст из документации Apple:
Примечание. CATextLayer отключает субпиксельное сглаживание при визуализации текста. Текст может быть нарисован с использованием субпиксельного сглаживания только тогда, когда он объединяется в существующий непрозрачный фон одновременно с растеризацией. Невозможно нарисовать текст с субпиксельным сглаживанием отдельно, будь то изображение или слой, отдельно до наличия пикселей фона, в которые будут вплетаться пиксели текста. Установка свойства непрозрачности слоя на ДА не изменяет режим рендеринга.
Второе предложение подразумевает, что можно получить красивый текст, если composites
превратить его в. existing opaque background at the same time that it's rasterized.
Отлично, но как мне составить его, как сделать его непрозрачным фоном и как растеризовать его?
Код, который они используют в своем примере меню киоска, выглядит следующим образом: (Это 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: См. Мой ответ ниже, чтобы узнать, как это было решено. сбг.
источник
Ответы:
Краткий ответ - Вам необходимо настроить масштабирование содержимого:
textLayer.contentsScale = [[UIScreen mainScreen] scale];
Некоторое время назад я узнал, что когда у вас есть собственный код рисования, вы должны проверять отображение сетчатки и соответствующим образом масштабировать графику.
UIKit
берет на себя большую часть этого, включая масштабирование шрифта.Не так с
CATextLayer.
Моя размытость возникла из-за того,
.zPosition
что не было нуля, то есть я применил преобразование к моему родительскому слою. Установив это значение на ноль, размытость исчезла и была заменена серьезной пикселизацией.После поиска высокого и низкого я обнаружил, что вы можете установить
.contentsScale
для,CATextLayer
а вы можете установить его[[UIScreen mainScreen] scale]
в соответствии с разрешением экрана. (Я предполагаю, что это работает для не сетчатки глаза, но я не проверял - слишком устал)После включения этого для меня
CATextLayer
текст стал четким. Обратите внимание - для родительского слоя это не обязательно.А размытость? Он возвращается, когда вы вращаетесь в 3D, но вы этого не замечаете, потому что текст сначала четкий, а пока он движется, вы не можете сказать.
Задача решена!
источник
textLayer.contentScale = [[UIScreen mainScreen] scale];
Кстати, мне тоже нравятся длинные ответы :)_textLayer.contentsScale = [[UIScreen mainScreen] scale];
У вас отсутствуетSwift
Установите для текстового слоя такой же масштаб, что и на экране.
textLayer.contentsScale = UIScreen.main.scale
Перед:
После:
источник
Прежде всего, я хотел указать, что вы пометили свой вопрос с помощью 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 к ближайшему целому пикселю, и это должно решить вашу проблему размытия.
источник
Перед настройкой 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]; }
источник
Вы должны сделать 2 вещи, первая из которых была упомянута выше:
Расширьте 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]; }
источник
Если вы искали здесь аналогичную проблему для CATextLayer в OSX, после долгих ударов головой о стену я получил четкий четкий текст, выполнив:
text_layer.contentsScale = self.window!.backingScaleFactor
(Я также установил такое же значение ContentScale для фонового слоя представлений).
источник
Это быстрее и проще: вам просто нужно установить 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];
источник