2013-08-08 18 views
6

creo UILabel e CATextLayer nella mia app con codice seguentecome impostare la posizione verticale del testo 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]; 
} 

e il risultato è

enter image description here

Il rosso è UILabel, quello verde è CALayer. I want to know how to vertical align the text in spettacoli CALayer , as the UILabel`.

+0

@Tark Questa domanda non è un duplicato. Questa domanda riguarda iOS. iOS non ha layoutManager disponibile a partire da iOS 11. –

risposta

1

Come nella documentazione del CATextLayer, non è possibile allineare verticalmente un testo. L'unica opzione è riposizionare il livello del testo in modo da allinearlo bene con l'etichetta. Ecco il codice per ottenere lo stesso

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

Il risultato è

enter image description here

+0

molto utile, grazie ... – 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

Ho problemi a trovare CAConstraint per iOS questa è solo una classe OSX? – amergin

+1

Sì, per iOS fare riferimento a https://github.com/regexident/DLConstraintLayout –

6

La risposta corretta è trovato here in Objective-C e lavori per iOS. Funziona sottoclasse lo CATextLayer e sovrascrive la funzione drawInContext.

Tuttavia, ho apportato alcuni miglioramenti al codice, come illustrato di seguito, utilizzando il codice di David Hoerl come base. I cambiamenti arrivano unicamente nel ricalcolare la posizione verticale del testo.

Ecco il codice per gli utenti di 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) 
} 
} 
7

In realtà, questo è ciò che funziona per 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 è quello che uso a "frame" mia area di delimitazione. Ciò mantiene il mio testo centrato verticalmente e orizzontalmente.

0

Swift versione 3 di @ di iamktothed risposta:

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