sizeWithFontメソッドは非推奨です。boundingRectWithSizeが予期しない値を返します


82

iOS7では、sizeWithFontは非推奨であるため、boundingRectWithSize(CGRect値を返す)を使用しています。私のコード:

 UIFont *fontText = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16];
                    // you can use your font.

 CGSize maximumLabelSize = CGSizeMake(310, 9999);

 CGRect textRect = [myString boundingRectWithSize:maximumLabelSize   
                             options:NSStringDrawingUsesLineFragmentOrigin
                             attributes:@{NSFontAttributeName:fontText}
                             context:nil];

 expectedLabelSize = CGSizeMake(textRect.size.width, textRect.size.height);

textRect、をmaximumLabelSize使用する場合とは異なるサイズで、自分よりも大きいサイズを取得していsizeWithFontます。この問題を解決するにはどうすればよいですか?


システムフォントやHelveticaだけでなく、すべてのフォントでこの問題が発生しています。
Nirav Jain 2013

あなたはそれを行う方法について何か考えがありますか?
Nirav Jain 2013

フォント名、テキスト、サイズの不一致の具体例が役立つ場合があります。
エイコ

以前は、iOS6でCTFramesetterSuggestFrameSizeWithConstraintsを使用して、常に正しい高さを返すattributedStringの高さを計算していました。iOS7では、CTFramesetterSuggestFrameSizeWithConstraintsとboundingRectWithSizeの両方で、間違った高さの結果が得られます。iOS7で導入されたバグであり、まだ解決策がないようです。
アーノルドタン

私も同じ問題に直面していますtttattributedlabelを使用する方が良い
Sri ..

回答:


151

新しいラベルを作成して使用するのはどうsizeThatFit:(CGSize)sizeですか?

UILabel *gettingSizeLabel = [[UILabel alloc] init];
gettingSizeLabel.font = [UIFont fontWithName:@"YOUR FONT's NAME" size:16];
gettingSizeLabel.text = @"YOUR LABEL's TEXT";
gettingSizeLabel.numberOfLines = 0;
gettingSizeLabel.lineBreakMode = NSLineBreakByWordWrapping;
CGSize maximumLabelSize = CGSizeMake(310, CGFLOAT_MAX);

CGSize expectSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];

編集:この上位コードはiOS 7以降には適していないため、以下を使用してください。

CGRect textRect = [myString boundingRectWithSize:maximumLabelSize   
                         options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading
                         attributes:@{NSFontAttributeName:fontText}
                         context:nil];

文字列に(<OL>、<LI>)のようなHTMLエンティティを追加している場合、このメソッドは機能しません。
Nirav Jain 2013

もう一度私の答えをチェックしてください!numberOfLinesプロパティを見逃しました!ごめんなさい!
クアンハ2013年

1
何時間にもわたる検索、実験、行き止まりの後、これはiOS7とXamarin / Monotouchで機能する唯一のソリューションです
Michael Rodrigues

26
フォントのサイズを計算するためのラベルを作成しますか?それはとても無駄です!
Ossir 2014

13
@Ossir、もっといいアイデアはありますか?
ルダ2014年

36

たぶん、この回答で提案されている方法に追加のオプションを提供する必要があります。

CGSize maximumLabelSize = CGSizeMake(310, CGFLOAT_MAX);
CGRect textRect = [myString boundingRectWithSize:maximumLabelSize   
                                         options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                      attributes:@{NSFontAttributeName: fontText}
                                         context:nil];

3
boundingRectWithSize壊れているようです。iOS 7、7.1.1でテストしましたが、正しくない結果が返されます。
RaffAl 2014

これは私には機能しませんでしたが、NSAttributedStringでboundingRectWithSizeを使用し、代わりにフォント属性を文字列に追加することは機能しました。
Sheepdogsheep 2014年

12
皆さん
SoftDesigner 2014

2
ceilは私には十分ではありませんでしたが、ceilを使用し、0.5を追加することでうまくいくことがわかりました
dwery 2015年

15

これが私の作業コードスニペットです:

NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:attributeDict];

NSString *headline  = [dict objectForKey:@"title"];  
UIFont *font        = [UIFont boldSystemFontOfSize:18];  
CGRect  rect        = [headline boundingRectWithSize:CGSizeMake(300, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];

CGFloat height      = roundf(rect.size.height +4)

計算された高さに4pxを追加しました。これは、これらの4pxがないと、1行が欠落しているためです。

このコードスニペットをtableViewで使用し、NSNumbersの配列に「高さ」を追加すると、デフォルトのtextLabelの正しいセルの高さが得られます。

textLabelのテキストの下にさらにスペースが必要な場合は、さらに4ピクセルを追加します。

****更新****

私は「40pxの幅のバグ」に同意しません。4pxは文字と1行の境界の間のスペースのデフォルトの高さであるため、高さが欠落している4pxであると叫びます。UILabelで確認できます。フォントサイズが16の場合、UILabelの高さは20が必要です。

ただし、最後の行に「g」などが含まれていない場合、測定値は4pxの高さを見逃す可能性があります。

少しの方法で再確認しました。ラベルの正確な高さは20、40、または60で、右の幅は300px未満です。

iOS6とiOS7をサポートするには、次の方法を使用できます。

- (CGFloat)heightFromString:(NSString*)text withFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
    CGRect rect;

    float iosVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (iosVersion >= 7.0) {
        rect = [text boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
    }
    else {
        CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
        rect = CGRectMake(0, 0, size.width, size.height);
    }
    NSLog(@"%@: W: %.f, H: %.f", self, rect.size.width, rect.size.height);
    return rect.size.height;
}

****アップグレード****

あなたのコメントのおかげで、私は次のように私の機能をアップグレードしました。sizeWithFontは非推奨であり、XCodeで警告が表示されるため、diagnostic-pragma-codeを追加して、この特定の関数呼び出し/コードブロックの警告を削除しました。

- (CGFloat)heightFromStringWithFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
    CGRect rect;

    if ([self respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
        rect = [self boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
    }
    else {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
        CGSize size = [self sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
        rect = CGRectMake(0, 0, size.width, size.height);
#pragma GCC diagnostic pop
    }
    return ceil(rect.size.height);
}

4pxのトピックに加えて、使用するフォントとフォントの太さに応じて、計算は異なる高さの値を返します。私の場合:HelveticaNeue-フォントサイズが16.0のMediumは、1行で20.0の行の高さを返しますが、2行で39.0、4行で78px-> 2行目から始まるすべての行で1pxが欠落していますが必要ですすべての行にfontsize + 4pxの行スペースを設定するには、高さの結果を取得する必要があります。
コーディングするときは、このことを覚えておいてください。
この「問題」に対する機能はまだありませんが、終了したらこの投稿を更新します。


1
フロート値をチェックするのではなく、おそらく[text responsesToSelector:@selector(boundingRectWithSize:options:attributes:context :)]を使用する必要があります。
サマ2014年

1
それは、この回答ではceil代わりに+ 4PTの機能、外観を使用することをお勧めしますstackoverflow.com/a/23563152/667483
サーフライダー

2

私が正しく理解している場合、あなたはboundingRectWithSizeを使用しています:sizeWithFontで取得するサイズを取得する方法と同じように(つまり、CGRectではなくCGSizeを直接必要とします)?

これはあなたが探しているもののように見えます:

非推奨のsizeWithFontの代わり:iOS 7では?

彼らはsizeWithAttributes:を使用して、sizeWithFontの代わりにサイズを取得しています。

次のようなものを使用しても、まだ間違ったサイズになりますか?

UIFont *fontText = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16];
                    // you can use your font.

expectedLabelSize = [myString sizeWithAttributes:@{NSFontAttributeName:fontText}];

しかし、どうすればCGSize maximumLabelSize = CGSizeMake(310、9999)を使用できますか?正しい高さと幅が必要です。
Nirav Jain 2013

1
sizeWithAttributes:に幅/高さを制約するように指示する属性はありますか?
Nirav Jain 2013

申し訳ありませんが、問題が何であるかわかりません。私が正しく理解していれば、フォントサイズでラベルのサイズを変更したいが、最大の高さ以下にしたい。sizeWithFontでそれを行うことができるとあなたは言いますが、このメソッドが非推奨になったので、別の方法が必要ですか?sizeWithFont:を使用していたのと同じ方法でsizeWithAttribues:をプラグインできるはずです。sizeWithFontを使用していたときに、ラベルサイズをどのように制限しましたか?sizeWithFontを使用して機能していたコードを投稿できますか?
vinaut 2013年

2
彼はsizeWithFont:constrainedToSize:lineBreakMode:を使用しており、constrainedToSize値をsizeWithAttributesに渡す方法はありません。
ZH。

2

@SoftDesignerのコメントは私のために働いた

CGRect descriptionRect = [description boundingRectWithSize:CGSizeMake(width, 0)
                                                       options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                                    attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}
                                                       context:nil];
result = ceil(descriptionRect.size.height);

1

ラベルの実行時のサイズを見つけるために、-boundingRectWithSize:options:attributes:context: methodを使用する代わりに、sizewithfontiOS7.0では非推奨になりました

以下のコードのように使用できます

CGSize constraint = CGSizeMake(MAXIMUM_WIDHT, TEMP_HEIGHT);
NSRange range = NSMakeRange(0, [[self.message body] length]);

NSDictionary *attributes = [YOUR_LABEL.attributedText attributesAtIndex:0 effectiveRange:&range];
CGSize boundingBox = [myString boundingRectWithSize:constraint options:NSStringDrawingUsesFontLeading attributes:attributes context:nil].size;
int numberOfLine = ceil((boundingBox.width) / YOUR_LABEL.frame.size.width);
CGSize descSize = CGSizeMake(ceil(boundingBox.width), ceil(self.lblMessageDetail.frame.size.height*numberOfLine));

CGRect frame=YOUR_LABEL.frame;
frame.size.height=descSize.height;
YOUR_LABEL.frame=frame;

ここでは、高さまたは幅を見つけるために、最大長に幅を指定する必要があります。

これを試してみてください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.