2010-02-05 19 views

risposta

37

Non penso che sia possibile aggiungere una sottoclasse UIView a un oggetto CALayer. Tuttavia, se si desidera disegnare del testo su un oggetto CALayer, è possibile farlo utilizzando le funzioni di disegno fornite in NSString UIKit additions come illustrato di seguito. Mentre il mio codice è fatto nel drawLayer del delegato: metodo inContext, lo stesso può essere usato nella sottoclasse 'drawInContext: method. Esiste una specifica funzionalità UILabel che si desidera sfruttare?

- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx { 
    CGContextSetFillColorWithColor(ctx, [[UIColor darkTextColor] CGColor]); 

    UIGraphicsPushContext(ctx); 
    /*[word drawInRect:layer.bounds 
      withFont:[UIFont systemFontOfSize:32] 
    lineBreakMode:UILineBreakModeWordWrap 
     alignment:UITextAlignmentCenter];*/ 

    [word drawAtPoint:CGPointMake(30.0f, 30.0f) 
      forWidth:200.0f 
      withFont:[UIFont boldSystemFontOfSize:32] 
     lineBreakMode:UILineBreakModeClip]; 

    UIGraphicsPopContext(); 
} 
+0

[[UIColor darkTextColor] impostato] funziona anche quando il contesto grafico è stato spinto – rpetrich

+0

@ Deepak Danduprolu Questo lavoro per me, ma io vagare perché dovrebbe chiamare la funzione push e pop per farlo funzionare – zeroleaf

4

tuo UILabel ha già un CALayer dietro di esso. Se stai assemblando diversi CALayer, puoi semplicemente aggiungere il layer di UILabel come sottostrato di uno di questi (usando la sua proprietà layer).

Se si tratta di un testo diretto in un livello che si desidera, le aggiunte UIKit NSString a cui Deepak punta sono la strada da percorrere. Per un esempio di questo in azione, lo Core Plot framework ha una sottoclasse CALayer indipendente dalla piattaforma Mac/iPhone che esegue il rendering del testo, CPTextLayer.

+0

Hey Brad, in realtà ho usato questa tecnica, (aggiungendo un layer di UILabel a un CALayer) e sembra che forse ha smesso di funzionare nell'SDK di iOS 8 di base? Ho iniziato a ricostruire una vecchia app che ho creato per esportare i video, e i sottolivelli del CALayer padre sembrano rimanere nulli con questo vecchio codice. Potrebbe essere qualcos'altro sbagliato, intenzione di continuare a cercare. –

+0

risolto. Per chiunque altro venga a cercare come compilare questo lavoro compilato su iOS 8 Base SDK, chiamare [display label.layer] prima di aggiungere il layer dell'etichetta a un altro CALayer. Credito: http://stackoverflow.com/questions/23171790/is-it-safe-to-add-a-stolen-uilabels-layer-to-some-other-calayers-sublayer –

2

Aggiungere un CATextLayer come sottolivello e impostare la proprietà stringa. Sarebbe più semplice e puoi usare facilmente un gestore di layout per renderlo molto generico.

+2

... _può facilmente utilizzare un layout manager _... Bene, in MacOS, sì, ma non in iOS. I CALayer in iOS non supportano i gestori di layout: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/Layout.html – Dalbergia

+0

Non lo sapeva! Grazie amico. –

135
 CATextLayer *label = [[CATextLayer alloc] init]; 
     [label setFont:@"Helvetica-Bold"]; 
     [label setFontSize:20]; 
     [label setFrame:validFrame]; 
     [label setString:@"Hello"]; 
     [label setAlignmentMode:kCAAlignmentCenter]; 
     [label setForegroundColor:[[UIColor whiteColor] CGColor]]; 
     [layer addSublayer:label]; 

     [label release]; 
+3

IMHO, questa è una soluzione più semplice di un CALayer personalizzato o di un delegato di livello a condizione che non sia necessario più di un semplice disegno di testo. CATextLayer sa già come disegnare il testo, quindi non è necessario reinventare la ruota. – Dalbergia

+0

@ Mshah2 perché il testo sta arrivando con effetto antialiasing? il testo sembra ingrandito – sreekanthk

+16

È necessario regolare la scala del contenuto del CALayer altrimenti si otterrà un testo sfocato sulla retina (@ 2x) o sui dispositivi @ 3x. Usa: label.contentsScale = [UIScreen mainScreen] .scale; – yonel

-1

sempre ricordarsi di togliere sottolivelli precedenti, se vuoi aggiungere un altro uno, per evitare vista duplicazione:

if let sublayers = layer.sublayers { 
    for sublayer in sublayers { 
     sublayer.removeFromSuperlayer() 
    } 
} 
Problemi correlati