2016-06-27 3 views
2

この質問は時折ポップアップしますが、まだ信頼できる解決策を見つけることができません。テキストビューを使用せずに属性付き文字列の推定高さを取得する

NSAttributedStringの高さを正確に見積もり、実際の高さを得るためにテキストを非表示のテキストビューにプルーフする必要はありません。 (テキストビューのアプローチは処理時間がかかります)。しかし、私は一貫して信頼できる値を取得することはできませんboundingRectWithSizeを使用します。それは私の目的にとって10の9倍に近いですが、それは十分ではありません。なぜなら、テキストの1行が見えない、切り捨てられた表示になることがあるからです。

サンプルコードは以下のとおりです。出力は次のとおりです。

2016-06-27 08:54:17.106 TextHeightTest[14045:7574151] estimated1 225.000000 
2016-06-27 08:54:17.108 TextHeightTest[14045:7574151] estimated2 209.000000 

最初の値は正しいです。 .hファイルで

:.mファイルで

@interface ViewController : UIViewController { 
    NSMutableDictionary *attributes; 
    UIFont *font; 
    UITextView *sizingTextView; 
    CGFloat width; 
} 

は:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    sizingTextView = [[UITextView alloc] init]; 
    font = [UIFont fontWithName:@"Helvetica" size:20]; 
    width = 300; 

    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 
    paragraphStyle.alignment = NSTextAlignmentLeft; 
    paragraphStyle.lineSpacing = 7; 
    paragraphStyle.maximumLineHeight = 20; 
    paragraphStyle.minimumLineHeight = 20; 

    attributes = [[NSMutableDictionary alloc] init]; 
    [attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName]; 
    [attributes setObject:font forKey:NSFontAttributeName]; 

    NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."; 
    NSAttributedString *attribStr = [[NSAttributedString alloc] initWithString:text attributes:attributes]; 

    CGFloat estimated1 = [self estimateInTextView:attribStr]; 
    NSLog(@"estimated1 %f", estimated1); 

    CGFloat estimated2 = [self estimateInSpace:text]; 
    NSLog(@"estimated2 %f", estimated2); 
} 

- (CGFloat)estimateInTextView:(NSAttributedString *)text { 
    sizingTextView.attributedText = text; 
    return [sizingTextView sizeThatFits:CGSizeMake(width, CGFLOAT_MAX)].height; 
} 

- (CGFloat)estimateInSpace:(NSString *)text { 
    CGRect rect = [text boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context:nil]; 
    return CGRectGetHeight(rect); 

} 

私は、任意の助けに感謝します。ありがとう。

答えて

2

テキストビューはテキストをテキストコンテナに置きます。既定では、テキストコンテナは上下に8ポイントずつ挿入されます。 textContainerInsetのドキュメントを参照してください。したがって、テキストビューは、テキスト自体が必要とするスペースよりも16ポイント高くなります。

テキストコンテナのlineFragmentPaddingのため、幅に基づいて行折り返しの違いがあります(デフォルトでは、左右に5ポイントが設定されています)。しかし、私はそれについては分かりません。

テストの場合、実際には文字列を所定のサイズの矩形で描画し、同じサイズのテキストビューでレンダリングした文字列と比較することができます。行が異なる点で壊れていないかどうかを確認します。両方の周りにフレームを描き、テキストがどこに差し込まれているかを確認します。

+0

ありがとうございます。私はcontentInsetについて聞いていましたが、今までtextContainerInsetについて聞いていませんでした。 UITextViewのtextContainerInsetをUIEdgeInsetsZeroに設定すると、2つの数字が同じになります。この問題は長い間私を悩ませています。とても有難い! (奨励金を授与することはできませんが、できるだけ早く奨励します)。 –

0

ドキュメントによると、「サイズを変更するために返されるサイズを使用するには、ceil関数を使用してその値を最も近いより高い整数に上げる必要があります。」(特定の例では、問題と思われる)。

関連する問題