How to set the vertical position of CATextLayer text?

I am creating UILabel and CATextLayer in my application using the following code

 - (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]; } 

and result

enter image description here

UILabel ; UILabel green 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` is displayed.

+6
source share
5 answers

Actually, this is what works for me:

 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 is what I use to frame my limited area. This keeps my text vertical and horizontal.

+7
source

The correct answer is found here in Objective-C and works for iOS . It works by subclassing CATextLayer and overriding the drawInContext function.

However, I made some improvements to the code, as shown below, using David Hoerl code as the basis. Changes occur solely when recalculating the vertical position of the text.

Here is the code for Swift users:

 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) } } 
+6
source
 { 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]; } 
+2
source

According to the CATextLayer documentation, there is no way to vertically align text. The only option is to move the text layer so that it matches the label well. Here is the code to achieve the same

 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]; 

Result

enter image description here

+1
source

Swift 3 version of @iamktothed answer:

 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() } } 
0
source

Source: https://habr.com/ru/post/951285/


All Articles