質問

レンダリングできる行数を考慮したNSStringの視覚的なサイズを測定しようとしています。ただし、sizeWithFontはnumberOfLinesプロパティを考慮しませんか?したがって、私のレイアウトアルゴリズムは、実際に必要なものよりもすべてを低く配置します。

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

誰もがiPhone SDKを使用してこれを行う方法を知っていますか?

役に立ちましたか?

解決

テキスト計算の最大高さのCGFLOAT_MAXの代わりに、これで1行のサイズを取得してみてください:

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

そしてそれをあなたが望む最大行数で乗算し、それをあなたが制限しているサイズの高さに差し込む。おそらく次のようになります:

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

行数を0に設定した場合、これは使用しないでください。その場合、最大の高さは0になります。その場合、CGFLOAT_MAXを使用する必要があります。

他のヒント

sizeWithFont:は文字列を切り捨てるので、複数行のUILabelをレイアウトするには、sizeWithFont:の代わりにUILabelのsizeToFitを使用します(アップルのドキュメントを参照)。次のコードは、テキストが指定されたサイズに収まるまでラベルのフォントサイズを縮小します...指定された高さに収まるとすぐに複数行のテキストが使用されます。

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

お気に入りのテキストとフォントのラベルで呼び出します:

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

startCharacterWrapAtSizeパラメーターを使用すると、指定したフォントサイズからcharacterWrapを使用することを選択できます。これにより、wordWrapが非常に小さなフォントを使用する場合にスペースを節約できます。

編集:バグ修正

1回の呼び出しで実行しようとするのではなく、次のような操作を行います(擬似コードはご容赦ください、遅れています):

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

}

当然のことながら、numberOfLinesを0に設定する必要があります。これにより、フレームワークは必要な行数で結果を計算します。 この質問もご覧ください。

もちろん、情報は呼び出されたり渡されたりするものがないため、考慮されません。文字列、サイズ、およびフォントを厳密に操作しています。行数が含まれているのはラベルです。

あなたの問題が正確に何なのかわかりません。高すぎたり短すぎたりするサイズになっていますか?テキストの行数は、結果の高さをフォントの高さで割ることで確認できます。フォントの高さは、アセンダーとディセンダーの値です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top