web-dev-qa-db-ja.com

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

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を使用しているときとはサイズが異なります。この問題を解決するにはどうすればよいですか?

79
Nirav

新しいラベルを作成して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];
148
Quang Hà

this answerで提案されている方法に追加オプションを提供する必要があるかもしれません:

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

ここに私の作業コードスニペットがあります:

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でこのコードスニペットを使用し、NSNumberの配列に「高さ」を追加すると、デフォルトのtextLabelの正しいセルの高さが取得されます。

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

****更新****

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

ただし、最後の行に「g」などが含まれていない場合、4ピクセルの高さを測定できない可能性があります。

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

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

15
Rikco

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

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

廃止されたsizeWithFontの置き換え:iOS 7では?

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

あなたはまだこのようなものを使用して間違ったサイズを取得していますか:

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

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

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

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

ラベルランタイムのサイズを見つけるためにsizewithfontはiOS 7.0では推奨されません。代わりに-boundingRectWithSize:options:attributes:context:メソッドを使用する必要があります

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

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;

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

私のために働いているこれを試してください。

1
Pratik