2009-07-30 12 views
5

Ich versuche die visuelle Größe eines NSString zu messen, der die Anzahl der Zeilen berücksichtigt, die ich rendern kann. SizeWithFont berücksichtigt jedoch die Eigenschaft numberOfLines nicht? Also mein Layout-Algorithmus positioniert alles niedriger als sie eigentlich sein müssen.iPhone UILabel sizeWithFont:

_price = [[UILabel alloc] init]; 
_price.text = myPriceValue; 
_price.lineBreakMode = UILineBreakModeWordWrap; 
_price.numberOfLines = 3; 
_price.backgroundColor = [UIColor clearColor]; 
_price.textColor = TTSTYLEVAR(colorPrice); 
/// the follow code ignores numberOfLines and just tells me the size of the whole block. 
// I'd like it to be aware of numberOfLines 
// 
CGSize priceSize = [_price.text sizeWithFont:_price.font 
     constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX) 
     lineBreakMode:UILineBreakModeWordWrap]; 

Weiß jemand, wie man das mit dem iPhone SDK macht?

Antwort

12

Statt CGFLOAT_MAX für die maximale Höhe des Textes Berechnung, versuchen, die Größe einer Zeile mit dieser bekommen:

[_price.text sizeWithFont:_price.font].height 

und dann die Zeilen durch die maximale # Multiplizieren Sie wollen, dann ist das Einstecken in die Höhe der Größe, auf die du dich beschränkst. Es würde wahrscheinlich so aussehen:

_price = [[UILabel alloc] init]; 
_price.text = myPriceValue; 
_price.lineBreakMode = UILineBreakModeWordWrap; 
_price.numberOfLines = 3; 
_price.backgroundColor = [UIColor clearColor]; 
_price.textColor = TTSTYLEVAR(colorPrice); 
CGFloat lineHeight = [_price.text sizeWithFont:_price.font].height; 
CGSize priceSize = [_price.text sizeWithFont:_price.font 
     constrainedToSize:CGSizeMake(maxWidth, lineHeight * _price.numberOfLines) 
     lineBreakMode:UILineBreakModeWordWrap]; 

Diese Mitteilung nicht verwenden, wenn Sie jemals Anzahl der Zeilen auf 0 als Ihre maximale Höhe eingestellt wird 0 in diesem Fall sein; Sie sollten dann CGFLOAT_MAX verwenden.

+2

sizeWithFont ist in iOS7 veraltet und stattdessen sollte boundingRectWithSize verwendet werden. –

-1

Natürlich berücksichtigt es das nicht, da nichts, was angerufen oder weitergegeben wird, diese Information enthält. Sie arbeiten ausschließlich mit Zeichenfolgen, Größen und Schriftarten. Es ist das Etikett, das die Anzahl der Zeilen enthält.

Ich bin mir nicht sicher, was genau dein Problem ist; Hast du eine Größe, die zu groß oder zu kurz ist, oder was? Sie können die Anzahl der Textzeilen herausfinden, indem Sie die Höhe des Ergebnisses durch die Höhe der Schrift dividieren, was der Wert der Oberlänge plus Unterlänge ist, glaube ich.

+0

Eigentlich sizeWithFont: constainedToSize: linebreak berücksichtigt einen Begrenzungsrahmen und Zeilenumbruch. Beachten Sie, dass sizeWithFont: forWidth: lineBreakMode funktioniert nicht mit mehreren Zeilen. –

0

Anstatt zu versuchen, es in einem Aufruf zu tun, so etwas zu tun (verzeihen Sie den Pseudo-Code, es ist spät):

NSString *s = _price.text; 
UIFont *font = _price.font; 
CGFloat fontSize = font.pointSize; 

while (TRUE) 
{ 
    CGSize priceSize = [s sizeWithFont: font constrainedToSize: 
     CGSizeMake(maxWidth, fontSize) lineBreakMode: UILineBreakModeWordWrap]; 

    if (/* priceSize is satisfactory */) 
    { 
     break; // Make sure this exits, eventually!!! 
    } 
    fontSize -= 1.0; // or a smaller decrement if you like 
    font = // new, smaller font 

} 
0

Die richtige Antwort ist, natürlich, müssen Sie NumberOfLines auf 0 setzen, Dies führt dazu, dass das Framework das Ergebnis mit so vielen benötigten Zeilen berechnet. Siehe auch this question.

+0

Nein, die Anzahl der Zeilen zu 0 ist unendliche Zeilen. aber ich möchte die Höhe von 3 Zeilen – CVertex

+0

Ah, ich sehe. Ich habe die Frage missverstanden. –

5

Verwenden Sie UIabels sizeToFit anstelle von sizeWithFont: um ein mehrzeiliges UILabel zu erstellen, da sizeWithFont: die Zeichenfolge abschneidet (siehe apple docs). Der folgende Code reduziert die Schriftgröße eines Etiketts, bis der Text passen in eine der angegebenen Größe ... mehrere Textzeilen werden so schnell verwendet werden, wie sie in der angegebenen Höhe passen:

-(void)setFontSizeOfMultiLineLabel: (UILabel*)label 
     toFitSize: (CGSize) size 
     forMaxFontSize: (CGFloat) maxFontSize 
     andMinFontSize: (CGFloat) minFontSize 
     startCharacterWrapAtSize: (CGFloat)characterWrapSize{ 

CGRect constraintSize = CGRectMake(0, 0, size.width, 0); 
label.frame = constraintSize; 
label.lineBreakMode = UILineBreakModeWordWrap; 
label.numberOfLines = 0; // allow any number of lines 

for (int i = maxFontSize; i > minFontSize; i--) { 

    if((i < characterWrapSize) && (label.lineBreakMode == UILineBreakModeWordWrap)){ 
     // start over again with lineBreakeMode set to character wrap 
     i = maxFontSize; 
     label.lineBreakMode = UILineBreakModeCharacterWrap; 
    } 

    label.font = [label.font fontWithSize:i]; 
    [label sizeToFit]; 
    if(label.frame.size.height < size.height){ 
     break; 
    }  
    label.frame = constraintSize; 
    } 
} 

Rufen Sie diese mit einem Label, die Ihren Lieblings Text und Schriftart hat:

UILabel *label = [[UILabel alloc] initWithFrame: CGRectZero]; 
label.backgroundColor = [UIColor clearColor]; 
label.textColor = [UIColor whiteColor]; 
label.text = text; 
label.font = [UIFont fontWithName: @"Helvetica" size: 16]; 
[self setFontSizeOfMultiLineLabel: label toFitSize: CGSizeMake(200, 44) forMaxFontSize: 16 andMinFontSize: 8 startCharacterWrapAtSize: 11]; 

der startCharacterWrapAtSize Parameter können Sie wählen characterWrap Ausgangsgröße bei der Angabe der Schriftart verwenden. Dies sollte Platz sparen, wenn wordWrap wirklich kleine Schriftarten verwenden würde.

edit: Bugfix

+0

Dies würde auch gut als Kategorie auf "UILabel" funktionieren –

Verwandte Themen