web-dev-qa-db-ja.com

「sizeWithFont:constrainedToSize:lineBreakMode:」は非推奨です:

Xcode 5でプロジェクトをiOS5.0からiOS7/iOS6に変換します。以下のコードは、コンパイル時の警告を与えています。

'sizeWithFont:constrainedToSize:lineBreakMode:'は非推奨です:最初にios 7.0で非推奨-使用-boundingRectWithSize:options:attribiutes:context

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0)
    {
        self.lblHidden.frame = CGRectMake(58, 228, 945, 9999);
        self.lblHidden.text = detailShareObj.pDesc;
        CGSize size = [detailShareObj.pDesc sizeWithFont:self.lblHidden.font constrainedToSize:self.lblHidden.frame.size lineBreakMode:NSLineBreakByWordWrapping];
        return 228.0+size.height+20;

    }
    else if (indexPath.section == 1)
    {
        NSString *tempPointStr = (self.shortDescArray)[indexPath.row];

        self.lblHidden.frame = CGRectMake(58, 0, 945, 9999);
        self.lblHidden.text = tempPointStr;
        CGSize size = [tempPointStr sizeWithFont:self.lblHidden.font
                               constrainedToSize:self.lblHidden.frame.size
                                   lineBreakMode:NSLineBreakByWordWrapping];

            return 50.0f;
    }

私は他の場所でいくつかの提案を試みましたが、コードに必要な修正を与えることで誰かが大いに感謝するのを手伝うことができれば、救助することはできません。

29
iSrini

非推奨の関数警告をマスクするだけではありません。彼らは理由のためにそれを廃止しました。 NSString + UIKitの一連の関数は、スレッドセーフではないUIStringDrawingライブラリに基づいていたため、この関数は廃止されたと思います。メインスレッド上ではなく(他のUIKit機能のように)実行しようとすると、予測できない動作が発生します。特に、複数のスレッドで同時に関数を実行すると、おそらくアプリがクラッシュします。これが、iOS 6でNSAttributedStringsにboundingRectWithSize:...メソッドを導入した理由です。これはNSStringDrawingライブラリの上に構築され、スレッドセーフです。

新しいNSString boundingRectWithSize:...関数を見ると、NSAttributeStringと同じ方法で属性配列を要求します。推測しなければならなかった場合、iOS 7のこの新しいNSString関数は、iOS 6のNSAttributeString関数の単なるラッパーです。

その点について、もしあなたがiOS 6とiOS 7だけをサポートしていたなら、私は間違いなくNSStringのsizeWithFont:...をNSAttributeStringのboundingRectWithSizeに変更します。奇妙なマルチスレッドコーナーケースが発生した場合、頭痛の種を大幅に減らすことができます。 NSStringのsizeWithFont:constrainedToSize:を変換する方法は次のとおりです。

以前は何でしたか:

NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
CGSize size = [text sizeWithFont:font 
               constrainedToSize:(CGSize){width, CGFLOAT_MAX}];

に置き換えることができます:

NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
NSAttributedString *attributedText =
    [[NSAttributedString alloc]
        initWithString:text
        attributes:@
        {
            NSFontAttributeName: font
        }];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
                                           options:NSStringDrawingUsesLineFragmentOrigin
                                           context:nil];
CGSize size = rect.size;

ドキュメントの言及に注意してください:

IOS 7以降では、このメソッドは小数サイズを返します(返されるCGRectのサイズコンポーネント)。返されたサイズを使用してビューのサイズを変更するには、ceil関数を使用して値を最も近い整数に上げる必要があります。

したがって、ビューのサイズ設定に使用する計算された高さまたは幅を引き出すには、次を使用します。

CGFloat height = ceilf(size.height);
CGFloat width  = ceilf(size.width);
64
Mr. T

IOS7とその下のバージョンの両方と互換性が必要な場合は、これを(ARCを使用して)試してください。

CGSize size;

if ([tempPointStr respondsToSelector:
     @selector(boundingRectWithSize:options:attributes:context:)])
{
  NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
  paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
  paragraphStyle.alignment = NSTextAlignmentLeft;

  NSDictionary * attributes = @{NSFontAttributeName : self.lblHidden.font,
                      NSParagraphStyleAttributeName : paragraphStyle};

  size = [tempPointStr boundingRectWithSize:self.lblHidden.frame.size
                                    options:NSStringDrawingUsesFontLeading
                                           |NSStringDrawingUsesLineFragmentOrigin
                                 attributes:attributes
                                    context:nil].size;
} else {
#pragma clang diagnostic Push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
  size = [tempPointStr sizeWithFont:self.lblHidden.font
                  constrainedToSize:self.lblHidden.frame.size
                      lineBreakMode:NSLineBreakByWordWrapping];
#pragma clang diagnostic pop
}

:これはelse-ifの場合の例にすぎません。必要に応じて変更する必要があるかもしれません。 ;)

44
Kjuly

IOS7の場合、以下を置き換えます。

CGSize size = [tempPointStr sizeWithFont:self.lblHidden.font
                       constrainedToSize:self.lblHidden.frame.size
                           lineBreakMode:NSLineBreakByWordWrapping];

と:

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; //set the line break mode
NSDictionary *attrDict = [NSDictionary dictionaryWithObjectsAndKeys:self.lblHidden.font, NSFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil];
CGSize size = [tempPointStr boundingRectWithSize:self.lblHidden.frame.size
                                         options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin
                                      attributes:attrDict context:nil].size;
10
Dave Chambers

次を使用できます。

UIFont *font = [UIFont boldSystemFontOfSize:16];

CGRect new = [string boundingRectWithSize:CGSizeMake(200, 300)
    options:NSStringDrawingUsesFontLeading 
    attributes:@{NSFontAttributeName: font} 
    context:nil];

CGSize stringSize= new.size;
2
user3575114

BoundingRectWithSize:options:attributes:contextには、文字列に「\ n」(改行)が含まれている場合に高さが正しく計算されないという問題があります。したがって、このコードは、指定された幅(inWidth)に対して各行のサイズを個別に計算します。

NSArray *brokenByLines=[string componentsSeparatedByString:@"\n"];
CGFloat height=0.0;
CGFloat maxWidth=0.0;
for (NSString* actString in brokenByLines) {
    CGRect tSize=[actString boundingRectWithSize:CGSizeMake(inWidth, 600) options:(NSStringDrawingUsesLineFragmentOrigin | NSLineBreakByWordWrapping) attributes:@{NSFontAttributeName: inFont} context:nil];
    if (maxWidth<tSize.size.width) {
        maxWidth=tSize.size.width;
    }
    height+=tSize.size.height;
}
CGSize size= CGSizeMake(ceil(maxWidth), ceil(height));
1
EckhardN

IOS 6.0以降をターゲットにしている場合でも、sizeWithFont:constrainedToSize:lineBreakMode:。プロジェクトのiOS Deployment Targetは6.0に設定されており、コンパイラはこれらの警告を表示しません。

(これは、「情報」セクション内の青いプロジェクトタブ(通常は左上のプロジェクトナビゲータペイン)をクリックして見つけることができます)。

IOS 7.0以降のみをターゲットにしている場合は、新しい方法boundingRectWithSize:options:attributes:context

Appleこの新しいメソッドのドキュメントをここで見つけてください。

1
JRG-Developer