2009-01-18 10 views
37

In meiner Frage "How do I get -[NSString sizeWithFont:forWidth:lineBreakMode:] to work?" erfuhr ich, dass -[NSString sizeWithFont:constrainedToSize:lineBreakMode:] tatsächlich war, was ich brauchte.Was ist - [NSString sizeWithFont: forWidth: lineBreakMode:] gut für?

Die Dokumentation für -[NSString sizeWithFont:forWidth:lineBreakMode:] Staaten erklärt, dass es den Text nicht tatsächlich zu zusätzlichen Zeilen umschließt. Also, wie würde ich es benutzen? (Beispiele würden helfen.)

Antwort

66

Es funktioniert auch für Multi-Line-Saiten.

Im Grunde ist es eine Funktion, mit der Sie sehen können, wie groß ein String sein wird, wenn er mit einem Font- und Zeilenumbruchmodus gerendert wird.

Ich benutze es an einigen Stellen in meiner Anwendung, wenn ich Text variabler Länge habe, den ich in einem bestimmten Bereich anzeigen möchte.

Standardmäßig zentriert UILabel den Text vertikal. Um den Text oben ausgerichtet zu haben, müssen Sie die Beschriftung auf die Höhe einstellen, die für die darin enthaltene Zeichenfolge erforderlich ist.

Ich verwende diese Methode, um dies zu tun.

Und Beispiel dafür, wie ich es benutzen würde, das zu tun ist wie folgt:

//Calculate the expected size based on the font and linebreak mode of your label 
CGSize maximumLabelSize = CGSizeMake(296,9999); 

CGSize expectedLabelSize = [yourString sizeWithFont:yourLabel.font 
         constrainedToSize:maximumLabelSize 
         lineBreakMode:yourLabel.lineBreakMode]; 

//adjust the label the the new height. 
CGRect newFrame = yourLabel.frame; 
newFrame.size.height = expectedLabelSize.height; 
yourLabel.frame = newFrame; 

Sie legen fest, wie groß der Bereich müssen Sie den Text in setzen, und dann diese Methode erfahren Sie, wie viel Platz es wird aufnehmen (wie erforderlich). Auch wenn der String die Grenzen des von Ihnen bereitgestellten Rect überläuft, können Sie sagen, und dann entschieden, wie der Text angezeigt wird.

Der Verweis darauf, der den Text nicht wirklich umschließt, ist da, weil diese Methode tatsächlich nichts mit dem Text tut. Es legt es quasi virtuell auf und gibt zurück, wie groß ein Gebiet sein würde, um es wirklich auszulegen.

Es liegt in der Verantwortung des Etiketts (oder des jeweiligen Containers, den Sie für den Text verwenden), die Verpackung/was immer sonst noch zu tun ist, durchzuführen.

Hoffe, dass hilft.

chris.

+0

newFrame.size.height = maximumLabelSize .height; SB: newFrame.size.height = expectedLabelSize.height; – JoBu1324

+0

funktioniert auch, wenn Sie in einem Rect zeichnen! – tipycalFlow

2

Es klingt, als wäre es gut für Single-Line-Etiketten. Zum Beispiel, wenn Sie eine Zeichenkette zeichnen, die abgeschnitten ist oder einen Zeilenumbruch hat, aber Sie werden nicht mehr als eine Zeile zeichnen. Es kann immer noch hilfreich sein, die genaue Höhe und Breite der Zeichenfolge zu kennen, sodass Sie sie genau dort positionieren können, wo Sie sie haben möchten (und andere UI-Elemente um sie herum zeichnen).

25

Für eine Weile dachte ich, diese Routine war einfach kaputt. Es klingt wie es ist die perfekte Routine für die Ausarbeitung wie hoch ein Stück Text ist, wenn in einer bestimmten Breite gewickelt. Dies ist jedoch nicht das, was es tut. Tatsächlich ist die zurückgegebene Höhe immer eine einzelne Linie. (Was sinnlos ist, nebenbei bemerkt. UIFont ‚s -leading den gleichen Wert zurückgibt)

die Dokumentation zum Zeitpunkt des Schreibens zu zitieren:

Obwohl es berechnet, wo Zeilenumbrüche auftreten würde, ist diese Methode nicht wickeln Sie den Text tatsächlich zu zusätzlichen Zeilen ein; [...]

Dieser Satz verwirrte mich für eine lange Zeit.Meine Gedanken liefen in folgenden Zeilen:

  • Computer-Zeilenumbrüche, aber nicht Umbruch. Eh?
  • Vielleicht meinen sie, dass der Empfänger NSString selbst nicht mutiert wird, um Zeilenumbrüche zu reflektieren? Aber ich erwarte das sowieso nicht?
  • Dieser Satz ist nicht mit sich selbst konsistent. Ich habe keine andere Wahl, als es zu ignorieren.

Es stellt sich jedoch heraus, dass es eine Bedeutung gibt, die zu dem Verhalten passt, das wir sehen. Es scheint, dass sie meinen, was ist:

Diese Routine berechnet wird, wo der ersten Zeilenumbruch auftreten wird, und alle Text danach wird für die Zwecke der Berechnung des Begrenzungsrahmen ignoriert.

Der zurückgegebene Begrenzungsrahmen hat daher die Höhe einer einzelnen Zeile und eine Breite bis zum angegebenen Maximum. (Die Breite kann geringer sein, je nachdem, wo der Zeilenumbruch berechnet wird, oder wenn der Text so kurz ist, dass er nicht die maximale Breite benötigt.)

Um, um, beantworten Sie die eigentliche Frage: Was ist gut? zum? Ich habe selbst nichts Nützliches gefunden: nur Dinge, bei denen ich dachte, dass es nützlich wäre, aber das war es nicht. Einige Dinge, die in den Sinn kommen, sind jedoch:

  • Centering ein einzeiliges Stück Text. Ich denke hier an Knöpfe und/oder Titel. (Obwohl UILabel und UIButton können Sie es tun, manchmal möchten Sie es selbst zeichnen.)
  • Berechnung der Grenzen für einen "Auszug" eines längeren Stück Text. Hier denke ich darüber nach, wo Sie vielleicht einen Ausschnitt aus einem viel größeren Stück Text zeigen möchten.
+2

+1 für die brutal ehrliche Frage "wofür ist es gut?" Ja, ich habe den gleichen Gedanken gehabt. Anyway, klingt wie NSString sizeWithFont: constrainedToSize: lineBreakMode ist was ich brauche. Vielen Dank – Chris

1

Hier ist etwas, was ich kam mit nach ein paar Prinzipien von PyjamaSam dem Beispiel der Anwendung:

AnnotationPin *myAnnotation = (AnnotationPin *)annotation; 

self = [super initWithAnnotation:myAnnotation reuseIdentifier:reuseIdentifier]; 
self.backgroundColor = [UIColor greenColor]; 
self.frame = CGRectMake(0,0,30,30); 
imageView = [[UIImageView alloc] initWithImage:myAnnotation.THEIMAGE]; 
imageView.frame = CGRectMake(3,3,20,20); 
imageView.layer.masksToBounds = NO; 
[self addSubview:imageView]; 
[imageView release]; 

CGSize titleSize = [myAnnotation.THETEXT sizeWithFont:[UIFont systemFontOfSize:12]]; 
CGRect newFrame = self.frame; 
newFrame.size.height = titleSize.height + 12; 
newFrame.size.width = titleSize.width + 32; 
self.frame = newFrame; 
self.layer.borderColor = [UIColor colorWithRed:0 green:.3 blue:0 alpha:1.0f].CGColor; 
self.layer.borderWidth = 3.0; 

UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(26,5,newFrame.size.width-32,newFrame.size.height-12)]; 
infoLabel.text = myAnnotation.title; 
infoLabel.backgroundColor = [UIColor clearColor]; 
infoLabel.textColor = [UIColor blackColor]; 
infoLabel.textAlignment = UITextAlignmentCenter; 
infoLabel.font = [UIFont systemFontOfSize:12]; 

[self addSubview:infoLabel]; 
[infoLabel release]; 

In diesem Beispiel ich einen benutzerdefinierten Stift auf eine MKAnnotation Klasse hinzufügen, die eine UILabel ändert die Größe nach der Textgröße. Es fügt auch ein Bild auf der linken Seite der Ansicht hinzu, so dass Sie einen Teil des Codes sehen, der den richtigen Abstand zum Umgang mit dem Bild und dem Padding verwaltet.

Der Schlüssel ist die Verwendung von CGSize titleSize = [myAnnotation.THETEXT sizeWithFont: [UIFont systemFontOfSize: 12]]; und dann die Dimensionen der Ansicht neu definieren. Sie können diese Logik auf jede Ansicht anwenden, aber es funktioniert nicht mit Zeilenumbrüchen wie Pyjamas.

Obwohl Pajamas Antwort für einige funktioniert, hat es für mich nicht funktioniert. Dies ist eine detaillierte Erklärung, die Sie sofort ausprobieren sollten, bevor Sie irgendwo anders hingehen, wenn Sie einen dynamischen benutzerdefinierten MKAnnotation Pin mit einem Bild und resizable UILabel möchten.

Verwandte Themen