5

複雑な PDF ドキュメントを作成するために印刷文字列のレイアウトを決定するために私が使用していた方法の多くは、iOS7 で廃止されました。ドキュメントでは、推奨されないすべての sizeWithFont メソッドの代わりとして使用する同じメソッドを呼び出します。

boundingRectWithSize:options:attributes:

それは問題ありsizeWithFont:ConstrainedTosize:lineBreakModeませんが、文字列を1行だけにしたい場合はどうすればよいですか? 最大高さに何を使用すればよいかわからないため、最初のパラメーターの値として渡す四角形がありません。

これは、特定のサイズに制限するときに私が持っているものです。

CGFloat maxHeightAllowable = _maxHeight;
CGSize issueTitleMaxSize = CGSizeMake(_issueListTitleColWidth - (kColumnMargin *2), maxHeightAllowable);
NSDictionary *issueTitleAttributes = [NSDictionary dictionaryWithObjectsAndKeys:_bodyFont, NSFontAttributeName, nil];
CGRect issueTitleRect = CGRectIntegral([issueTitleText boundingRectWithSize:issueTitleMaxSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:issueTitleAttributes context:nil]);
CGSize issueTitleSize = issueTitleRect.size;

maxHeight がわからない場合、または実際には 1 行の高さがまさに私が見つけようとしているものである場合、この同じ方法をどのように使用しますか?

彼らが NSAttributed 文字列と自動レイアウトの互換性を推進している理由はわかりますが、なぜこれらを非推奨にするのですか? 私の場合、交換には、以前は 1 または 2 だったステップが 4 または 5 ステップになりました。

T氏が提案したように、フォントのlineHeightプロパティを使用して、これらのメソッドを置き換えを大幅に簡素化するカテゴリにしました。

#import "NSString+SizingForPDF.h"

@implementation NSString (SizingForPDF)

-(CGSize)integralSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)maxSize
{
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil];
    CGRect rect = CGRectIntegral([self boundingRectWithSize:maxSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:attributes context:nil]);
    return rect.size;
}

-(CGSize)integralSizeWithFont:(UIFont *)font maxWidth:(CGFloat)maxWidth numberOfLines:(NSInteger)lines
{
    if (lines == 0) {
        lines = 1;
    }
    NSDictionary *attributes = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
    CGFloat height = font.lineHeight * lines;
    CGSize maxsize = CGSizeMake(maxWidth, height);
    CGRect rect = CGRectIntegral([self boundingRectWithSize:maxsize options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesFontLeading attributes:attributes context:nil]);
    return rect.size;
}

@end
4

1 に答える 1

15

1 行の高さだけを探している場合は、フォントのlineHeightプロパティをそのまま使用できませんか? これを使用して、ラベルの高さを設定したり、問題なく要素の高さを適切に予測したりします。この点でpdfドキュメントが異なるかどうかはわかりません。

さらに、一連の NSString+UIKit 関数 (sizeWithFont:...など) は、スレッドセーフではない UIStringDrawing ライブラリに基づいていたため、これらの関数は非推奨になったと思います。メイン スレッド以外で実行しようとすると (他の UIKit 機能と同様)、予期しない動作が発生します。特に、関数を複数のスレッドで同時に実行すると、アプリがクラッシュする可能性があります。これが、iOS 6 でboundingRectWithSize:...NSAttributedStrings のメソッドが導入された理由です。これは NSStringDrawing ライブラリの上に構築されており、スレッドセーフです。

その点で、iOS 6 と iOS 7 のみをサポートしている場合は、すべての NSStringsizeWithFont:...を 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);
于 2013-09-23T03:36:26.340 に答える