2013-08-08 10 views
6

Ich schaffe UILabel und CATextLayer in meiner appWie wird die vertikale Position von CATextLayer-Text festgelegt?

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

und das Ergebnis ist

enter image description here

Die rote ist UILabel, die grüne ist CALayer. I want to know how to vertical align the text in CALayer , as the UILabel` zeigt folgenden Code verwendet.

+0

@Tark Diese Frage ist kein Duplikat. Diese Frage bezieht sich auf iOS. iOS hat keinen layoutManager seit iOS 11 verfügbar. –

Antwort

1

Gemäß der CATextLayer-Dokumentation gibt es keine Möglichkeit, einen Text vertikal auszurichten. Die einzige Möglichkeit besteht darin, die Textebene so neu zu positionieren, dass sie gut mit dem Etikett übereinstimmen. Hier ist der Code der gleichen

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

Das Ergebnis zu erreichen, ist

enter image description here

+0

sehr hilfreich, danke ... – Enix

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

} 
+0

Ich habe Probleme, CAConstraint für iOS zu finden ist dies nur eine OSX-Klasse? – amergin

+1

Yup, für iOS beziehen Sie sich auf https://github.com/regexident/DLConstraintLayout –

6

Die richtige Antwort here in Objective-C und Werke für iOS gefunden wird. Es funktioniert, indem es die CATextLayer Unterklasse bildet und die drawInContext Funktion außer Kraft setzt.

Allerdings habe ich einige Verbesserungen an dem Code vorgenommen, wie unten gezeigt, mit David Hoerls Code als Grundlage. Die Änderungen kommen ausschließlich in der Neuberechnung der vertikalen Position des Textes. Hier

ist der Code für Swift-Benutzer:

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) 
} 
} 
7

Eigentlich ist das, was für mich funktioniert:

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 ist, was ich verwenden, um "Rahmen" mein Begrenzungsbereich. Dadurch bleibt mein Text vertikal und horizontal zentriert.

0

Swift 3-Version von @ iamktothed Antwort:

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() 
    } 
} 
Verwandte Themen