web-dev-qa-db-ja.com

UILabel / UITableViewCellの複数行のテキストの高さの計算:計算時と実際の描画時の結果が異なる

この一般的なトピックは、ここで何度も尋ねられています。UITableViewCellsをさまざまな量のテキスト、したがってさまざまな高さでレンダリングする方法です。正解は、sizeWithFont:constrainedToSize:lineBreakMode:を使用して、heightForRowAtIndexPathのTable View Controllerデリゲートの高さを計算することです。その後、セルが描画され、必要に応じて[label sizeToFit]のようなものを使用します。すべてが魔法のように機能します。

私の問題:sizeWithFont:が実際の描画とは異なる寸法を返すため、一部のセルがラッピングされています。

具体的な例:

テキストは次のとおりです。「@ BillGatesは、1993年にNECからセクシーな1/4インチの厚板があったことを忘れています。今週何が起こるかは、ハードウェアについてではありません!」

CGSize theSize = [text sizeWithFont:[UIFont systemFontOfSize:17.0f] constrainedToSize:CGSizeMake(310.0f, FLT_MAX) lineBreakMode:UILineBreakModeWordWrap];
NSLog(@"calculated size for %@: %f, %f",text, theSize.width, theSize.height);

これは、306.000000、84.000000を返します。 (つまり、17ピクセルのフォントと4ピクセルの行間隔で4行、21ピクセルの行送り。)良い。

ただし、後で実際にセルを描画する場合:

label = (UILabel *)[cell viewWithTag:3];
label.text = [NSString stringWithFormat:@"%@", text];
label.lineBreakMode = UILineBreakModeWordWrap;
label.font = [UIFont systemFontOfSize:17.0f];
CGSize labelSize;   
labelSize = label.frame.size;
NSLog(@"label size before resizing: %f, %f", labelSize.width, labelSize.height);
[label sizeToFit];
labelSize = label.frame.size;
NSLog(@"label size after resizing: %f, %f for text %@", labelSize.width, labelSize.height,text);

(UILabelはNIBからUITableViewCellの一部としてロードされます。IBでは、310px幅に設定します。)

これは、上記とまったく同じサイズを返す必要があります。代わりに、sizeToFit呼び出し後のディメンションとして281.000000、105.000000を取得します。描画時に4行ではなく5行になり、テキストがあふれて、UIに波及が表示されます。

そのため、同じテキストに対して、2つの異なるディメンションが計算されており、理解できません。 UILabelについてですか?いくつかの内部マージンがありますか?これは一部のテキストで発生し続けますが、他のテキストでは発生しません。また、文字列に特定の何かを追跡できませんでした。ランダムに見える。 このトピック は、高さの計算と実際の描画の2つの処理パスがあることを強調しています。これは私が見ているものと一致しています。しかし、私は正確に何が起こっているのか、それを修正する方法を理解していません。

質問:計算された2つの異なるサイズが表示されるのはなぜですか?どうすれば修正できますか?

39
Jaanus

もちろん、解決策は明らかです投稿後数秒。他の人にも役立つかもしれません...

sizeWithFont:によるサイズは正しいものでした。 [label sizeToFit]はラベルのフレームの幅を縮小するため、上記の方法で計算したサイズは正しくありませんでした。同じコードへの後続の呼び出しで、すでに縮小されている可能性のあるフレームから開始しました。

修正は、サイズを合わせる前にフレームwidthを既知の適切な幅に単純にリセットすることでした。

CGRect labelFrame = label.frame;
labelFrame.size.width = 310;
label.frame = labelFrame;
[label sizeToFit];
36
Jaanus

複数行のラベルの場合、設定が必要です

cell.textLabel.numberOfLines = 0;

その後

[cell.textLabel sizeToFit];

ただし、きれいに表示するには、パディングピクセルを追加する必要があります。そして、あなたのアプリは素晴らしいものになるでしょう!

12
Oleg
 titleSize = [title sizeWithFont:[UIFont systemFontOfSize:(CGFloat)17.0]
                                constrainedToSize:CGSizeMake(280, 2000)
                                    lineBreakMode:NSLineBreakByWordWrapping];
6
Aswathi