как установить вертикальную позицию текста CATextLayer?

Я создаю UILabel и CATextLayer в своем приложении, используя следующий код

 - (void)viewDidLoad { [super viewDidLoad]; self.textLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 90, 20, 20)]; self.textLabel.text = @"1"; self.textLabel.font = [UIFont systemFontOfSize:12]; self.textLabel.backgroundColor = [UIColor redColor]; [self.view addSubview:self.textLabel]; self.textLayer = [CATextLayer layer]; [self.textLayer setString:@"1"]; [self.textLayer setFont:(__bridge CFTypeRef)([UIFont systemFontOfSize:12])]; self.textLayer.backgroundColor = [UIColor greenColor].CGColor; self.textLayer.frame = CGRectMake(70, 90, 50, 20); [self.view.layer addSublayer:self.textLayer]; } 

и результат

введите описание изображения здесь

Красный – UILabel , зеленый – CALayer. I want to know how to vertical align the text in CALayer. I want to know how to vertical align the text in CALayer , as the показывает UILabel`.

Правильный ответ найден здесь в Objective-C и работает для iOS . Он работает путем подкласса CATextLayer и переопределения функции drawInContext .

Тем не менее, я сделал некоторые улучшения для кода, как показано ниже, используя код Дэвида Хёрля в качестве основы. Изменения происходят исключительно при пересчете вертикального положения текста.

Вот код для пользователей Swift:

 class LCTextLayer : CATextLayer { // REF: http://lists.apple.com/archives/quartz-dev/2008/Aug/msg00016.html // CREDIT: David Hoerl - https://github.com/dhoerl // USAGE: To fix the vertical alignment issue that currently exists within the CATextLayer class. Change made to the yDiff calculation. override init!() { super.init() } override init!(layer: AnyObject!) { super.init(layer: layer) } required init(coder aDecoder: NSCoder) { super.init(layer: aDecoder) } override func drawInContext(ctx: CGContext!) { let height = self.bounds.size.height let fontSize = self.fontSize let yDiff = (height-fontSize)/2 - fontSize/10 CGContextSaveGState(ctx) CGContextTranslateCTM(ctx, 0.0, yDiff) super.drawInContext(ctx) CGContextRestoreGState(ctx) } } 

На самом деле, это то, что работает для меня:

 self.layer.addSublayer(textLayer) textLayer.font = font textLayer.fontSize = font.pointSize textLayer.frame = CGRectMake(self.layer.bounds.origin.x, ((self.layer.bounds.height - textLayer.fontSize) / 2) - lineWidth, self.layer.bounds.width, self.layer.bounds.height) textLayer.alignmentMode - kCAAlignmentCenter textLayer.contentsScale = UIScreen.mainScreen().scale 

LineWidth – это то, что я использую для «рамки» моей ограниченной области. Это держит мой текст по вертикали и горизонтали.

 { CATextLayer *label = [[CATextLayer alloc] init]; [label setFont:@"Helvetica-Bold"]; [label setFontSize:16]; [label setFrame:NSMakeRect(0, 0, NSWidth(self.frame) / 2., NSHeight(self.frame))]; [label setString:@"ON"]; [label setAlignmentMode:kCAAlignmentCenter]; [label setForegroundColor:[[NSColor whiteColor] CGColor]]; _rootLayer.layoutManager = [CAConstraintLayoutManager layoutManager]; [label addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidY relativeTo:@"superlayer" attribute:kCAConstraintMidY]]; [label addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidX relativeTo:@"superlayer" attribute:kCAConstraintMidX]]; [_rootLayer addSublayer:label]; } 

В соответствии с документацией CATextLayer нет возможности вертикально выровнять текст. Единственный вариант – переместить текстовый слой так, чтобы он хорошо совпадал с меткой. Вот код для достижения того же

 CGFloat offsetY = 0; UIFont *textFont = [UIFont systemFontOfSize:14.0f]; //if system version is grater than 6 if(([[[UIDevice currentDevice] systemVersion] compare:@"6" options:NSNumericSearch] == NSOrderedDescending)){ offsetY = (textFont.capHeight - textFont.xHeight); } self.textLayer = [CATextLayer layer]; self.textLayer.backgroundColor = [UIColor greenColor].CGColor; self.textLayer.frame = CGRectMake(70, 90+offsetY, 50, 20); [self.view.layer addSublayer:self.textLayer]; [self.textLayer setContentsScale:[UIScreen mainScreen].scale]; [self.textLayer setForegroundColor: [UIColor blackColor].CGColor]; [self.textLayer setString:@"1"]; [self.textLayer setFont:(__bridge CFTypeRef)(textFont)]; [self.textLayer setFontSize:14.0f]; 

В результате

введите описание изображения здесь

Swift 3 версии ответа @ iamktothed:

 class VerticallyCenteredTextLayer : CATextLayer { // REF: http://lists.apple.com/archives/quartz-dev/2008/Aug/msg00016.html // CREDIT: David Hoerl - https://github.com/dhoerl // USAGE: To fix the vertical alignment issue that currently exists within the CATextLayer class. override func draw(in ctx: CGContext) { let fontSize = self.fontSize let height = self.bounds.size.height let deltaY = (height-fontSize)/2 - fontSize/10 ctx.saveGState() ctx.translateBy(x: 0.0, y: deltaY) super.draw(in: ctx) ctx.restoreGState() } } 
  • Установить размер шрифта UILabel в соответствии с его размером кадра?
  • UIAppearance для нескольких UILabels
  • Перетаскиваемая метка - ios
  • Получите Int из UILabel Swift
  • Swift не может присвоить значение типа '()', чтобы набрать 'String?'
  • Центрировать по вертикали в UILabel с автозагрузкой
  • UILabel не отображается в подробном виде
  • Сохраняйте UILabel с центром в UIView, когда изменяется длина символов. iOS, цель C
  • Установка вертикального выравнивания усеченных хвостов для NSAttributedString с NSTextAttachment
  • Добавление подпрограммы и ее программное программирование с ограничениями
  • Получить строку первой строки в UILabel
  • Interesting Posts

    Добавить атрибут фотографии в коллекцию пользователей в Кинви

    Соединение с активами было прервано или активы умерли

    Какой из них лучше определять пользователей в быстром управлении памятью? Enum, Struct или класс в swift?

    Как извлечь изображения из видео?

    iOS: сохранение данных JFIF / EXIF ​​при сохранении в кадре камеры

    Как я могу получать уведомления о баннерном уведомлении в iOS?

    Когда я делаю центр масштабирования смещен в левое нижнее

    Как изменить UITableViewCell с помощью UIButton?

    Swift SpriteKit PhysicsBody принудительно, как опция, с помощью Xcode

    При использовании Apple Hosted Content с покупкой приложения на iOS можно загрузить контент перед покупкой?

    PFQuery FindObjectsInBackground Возвращает 0

    Добавление подзаголовка в пользовательский viewForHeaderInSection прерывает навигацию VoiceOver

    Только ячейка MonoTouch.Dialog Image

    Специальное приложение для распространения является серым, после перехода с iTunes на iPhone

    добавление словарного объекта в UITableViewCell

    Давайте будем гением компьютера.