2010-12-29 5 views
2

Mögliche Duplizieren:
Change NSTextField font size to fitWie passt man einen NSString optimal in ein Rechteck?

Ich versuche, eine Zeichenfolge mit variabler Länge zu passen (die Anzahl der Wörter in der Kette ist unbekannt) innerhalb eines bestimmten Rechtecks. Ich möchte die Saite optimal so groß wie möglich gestalten und in das Rechteck passen. Außerdem sollte die Zeichenfolge Zeilenumbruch sein, wenn mehr als ein Wort vorhanden ist und ein Wort nicht teilweise in mehreren Zeilen gerendert werden soll. Mein Problem ist manchmal ein Wort ist teilweise in mehreren Zeilen wie unten dargestellt. Irgendwelche Vorschläge, was ich falsch machen könnte?

Vielen Dank.

alt text

ich eine NSLayoutManager, NSTextStorage und NSTextContainer verwenden.

ich initialisieren alles wie folgt:

textStorage = [[NSTextStorage alloc] initWithString:@""]; 
    layoutManager = [[NSLayoutManager alloc] init]; 
    textContainer = [[NSTextContainer alloc] init]; 

    [layoutManager addTextContainer:textContainer];  
    [textStorage addLayoutManager:layoutManager]; 

    paraStyle = [[NSMutableParagraphStyle alloc] init]; 
    [paraStyle setLineBreakMode:NSLineBreakByWordWrapping]; 
    [paraStyle setParagraphStyle:[NSParagraphStyle defaultParagraphStyle]]; 
    [paraStyle setAlignment:NSCenterTextAlignment]; 

ich dann die Schriftgröße wie folgt berechnen,

- (float)calculateFontSizeForString:(NSString *)aString andBoxSize:(NSSize)aBox 
{ 
    //Create the attributed string 
    NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:aString]; 
    [textStorage setAttributedString:attrString]; 
    [textContainer setContainerSize:NSMakeSize(aBox.width, FLT_MAX)]; 
    [attrString release]; //Clean up 

    //Initial values 
    float fontSize = 50.0; 
    float fontStepSize = 100.0; 
    NSRect stringRect; 
    BOOL didFindHeight = NO; 
    BOOL shouldIncreaseHeight = YES; 

    while (!didFindHeight) 
    { 
     NSMutableDictionary *stringAttributes = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
               paraStyle, NSParagraphStyleAttributeName, 
               [NSFont systemFontOfSize:fontSize], NSFontAttributeName, nil]; 

     [textStorage addAttributes:stringAttributes range:NSMakeRange(0, [textStorage length])]; 

     (void)[layoutManager glyphRangeForTextContainer:textContainer];  
     stringRect = [layoutManager usedRectForTextContainer:textContainer]; 

     if (shouldIncreaseHeight) 
     { 
      if (stringRect.size.height > aBox.height) 
      { 
       shouldIncreaseHeight = NO; 
       fontStepSize = fontStepSize/2; 
      } 

      fontSize += fontStepSize; 
     } 
     else 
     { 
      if (stringRect.size.height < aBox.height) 
      { 
       shouldIncreaseHeight = YES; 

       fontStepSize = fontStepSize/2; 

       if (fontStepSize <= 0.5) 
       { 
        didFindHeight = YES; 
       } 
      } 

      if ((fontSize - fontStepSize) <= 0) 
      { 
       fontStepSize = fontStepSize/2;    
      } 
      else 
      { 
       fontSize -= fontStepSize; 
      } 
     } 
    } 

    return fontSize; 
} 

Antwort

1

Bitte suchen Sie vor der Veröffentlichung. Dies kommt wiederholt vor. Die letzte Antwort ist here, aber ich denke, es gibt weitere vollständige Antworten mit Code-Listings an anderer Stelle.

Mein zugegebenermaßen einfaches Beispiel zeigt, wie man es ohne einen Textcontainer und Layoutmanager macht, aber Ihr Ansatz ist robuster. Leider ist Brute-Force (Dimensionierung, bis es passt) der einzige Ansatz, um die beste Anpassung zu bestimmen.

Verwandte Themen