2009-08-19 14 views
18

C'è un metodo per disegnare il testo nel mezzo di un rettangolo. Riesco a trovare vari allineamenti, ma nulla di ciò che ho provato può centrare verticalmente il testo in un rect.iPhone - Come disegnare il testo nel mezzo di un rect

C'è un metodo semplice per eseguire questa operazione oppure esiste un modo per centrare un rettangolo e quindi disegnarlo?

Sto disegnando direttamente in CGContext, provando a utilizzare NSString :: drawWithRect o qualcosa di simile, poiché non desidero davvero dover aggiungere un'etichetta solo per rendere un testo di base.

risposta

29

Beh, la proprietà font pointSize corrisponde direttamente l'altezza in pixel di un NSString disegnato in quel UIFont, così la formula sarebbe qualcosa di simile:

- (void) drawString: (NSString*) s 
      withFont: (UIFont*) font 
      inRect: (CGRect) contextRect { 

    CGFloat fontHeight = font.pointSize; 
    CGFloat yOffset = (contextRect.size.height - fontHeight)/2.0; 

    CGRect textRect = CGRectMake(0, yOffset, contextRect.size.width, fontHeight); 

    [s drawInRect: textRect 
     withFont: font 
    lineBreakMode: UILineBreakModeClip 
     alignment: UITextAlignmentCenter]; 
} 

UITextAlignmentCenter gestisce l'horizontal centraggio, quindi usiamo l'intera larghezza del contextRect. Il lineBreakMode può essere quello che vuoi.

+0

Questo è molto vicino a quello che alla fine sono andato con. Grazie – Xetius

+3

Sei il benvenuto. Cosa hai cambiato, se posso chiedere? – Amagrammer

+6

Ciao, so che è piuttosto vecchio, ma l'ho usato e ho dovuto cambiare. La mia modifica è stata la riga di testo CRLRect .... L'ho modificato in ... CGRect textRect = CGRectMake (contextRect.origin.x, contextRect.origin.y + yOffSet, contextRect.size.width, fontHeight); – Fogmeister

2

In iOS 6 vengono attribuite stringhe e allineamenti di paragrafo, quindi diventa molto più semplice e potente. In questo esempio, tracciamo un grande rosso "A" nel bel mezzo di un rettangolo:

NSMutableParagraphStyle* p = [NSMutableParagraphStyle new]; 
p.alignment = NSTextAlignmentCenter; 
NSAttributedString* bigA = 
    [[NSAttributedString alloc] initWithString:@"A" attributes:@{ 
     NSFontAttributeName: [UIFont fontWithName:@"Georgia" size:100], 
     NSForegroundColorAttributeName: [UIColor redColor], 
     NSParagraphStyleAttributeName: p 
    }]; 
[bigA drawInRect:CGRectMake(0,0,200,200)]; 
+3

Centra il testo orizzontalmente, ma non lo allinea verticalmente. – Clay

+0

"Allinea verticalmente"? Disegnalo dove vuoi. Oppure disegnalo in qualcosa (ad esempio un'immagine) e mettilo dove vuoi. – matt

+8

Giusto - Capisco cosa stai dicendo. Stavo solo cercando di far notare che penso che la domanda riguardasse come allineare qualcosa verticalmente al centro di qualcosa di più grande. Dato un 'NSRect' predeterminato, ad esempio, come si può usare' [myString drawInRect: myRect] 'o una variante per posizionare la stringa al centro verticale di' myRect'. Per Cocoa, lo faccio includendo la categoria 'NS (Attribuito) Stringa + Geometria' da https://github.com/jerrykrinock/CategoriesObjC e facendo un po 'di semplice matematica con' - (float) heightForWidth: (float) larghezza 'metodo. – Clay

1

Sono d'accordo con la risposta di amagrammer, tranne che per un piccolo cambiamento: io uso font.lineSize per ottenere l'altezza corretta. Suppongo che sizeWithFont vi darà la spessore di linea così

+0

Sono d'accordo con te, ma lineSize o lineHeight? – damithH

0

ho trovato questo codice funziona piuttosto bene:

NSString *text = @"A bit of text to draw"; 
UIFont *font = [UIFont systemFontOfSize:12]; 
CGRect textFrame = (CGRect) 
{ 
    .size.width = 150, 
    .size.height = 150, 
}; 
CGSize textSize = [text sizeWithFont:font constrainedToSize:textFrame.size lineBreakMode:NSLineBreakByWordWrapping]; 
CGRect newTextFrame = CGRectInset(textFrame, 0, (textFrame.size.height - textSize.height)/2); 
[text drawInRect:newTextFrame withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentCenter]; 

Il testo, font e contenente telaio può venire da qualsiasi luogo, quindi basta utilizzare la stessa linea modalità di interruzione quando si esegue il calcolo e il disegno.

17

Ecco una versione aggiornata per iOS7.0 +.

Ho anche migliorato la risposta di cui sopra utilizzando il metodo sizeWithAttributes: che restituisce i limiti del testo che consente di posizionare correttamente il testo prima di disegnarlo. Ciò elimina la necessità di hardcode di eventuali regolazioni che si interrompono se si utilizza un font di dimensioni diverse o se si utilizza un font diverso.

- (void) drawString: (NSString*) s 
      withFont: (UIFont*) font 
      inRect: (CGRect) contextRect { 

    /// Make a copy of the default paragraph style 
    NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 
    /// Set line break mode 
    paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail; 
    /// Set text alignment 
    paragraphStyle.alignment = NSTextAlignmentCenter; 

    NSDictionary *attributes = @{ NSFontAttributeName: font, 
            NSForegroundColorAttributeName: [UIColor whiteColor], 
            NSParagraphStyleAttributeName: paragraphStyle }; 

    CGSize size = [s sizeWithAttributes:attributes]; 

    CGRect textRect = CGRectMake(contextRect.origin.x + floorf((contextRect.size.width - size.width)/2), 
           contextRect.origin.y + floorf((contextRect.size.height - size.height)/2), 
           size.width, 
           size.height); 

    [s drawInRect:textRect withAttributes:attributes]; 
} 
Problemi correlati