2010-12-29 10 views
2

可能性の重複:
Change NSTextField font size to fitNSStringを長方形に最適にフィットさせる方法は?

私は与えられた長方形の内側(文字列内の単語の数は不明である)、可変長の文字列に合うようにしようとしています。文字列のサイズを可能な限り大きくし、矩形の内側に収まるように文字列のサイズを最適にしたい。さらに、複数の単語がある場合には文字列を折り返す必要があり、複数の行に部分的に単語を表示しないようにする必要があります。私の問題は、以下に示すように、単語が複数の行に部分的にレイアウトされていることがあります。私が間違っていると思われることに関する提案はありますか?

ありがとうございます。

alt text

私はNSLayoutManager、NSTextStorageとNSTextContainerを使用しています。

次のように私はすべてを初期化します。

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]; 

次のように私は、フォントサイズを計算し、

- (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; 
} 

答えて

1

投稿する前に検索してください。これは繰り返し起こります。最新の回答はhereですが、コードリストの他の箇所ではより完全な回答があると思います。

私は間違いなく単純な例として、テキストコンテナとレイアウトマネージャを使用せずに行う方法を示していますが、あなたのアプローチはより堅牢です。残念なことに、ブルートフォース(フィットするまでのサイジング)は、ベストフィットを決定する唯一のアプローチです。

関連する問題