1

高さ測定文字列の手順を探していましたが、別のスタックオーバーフローの質問でこれを見つけました。私の質問は、改行を文字の折り返しに変更した場合、どうすればこのコードを更新できますか?

- (NSSize)sizeForWidth:(float)width 
                height:(float)height {
    NSSize answer = NSZeroSize ;
     gNSStringGeometricsTypesetterBehavior =   NSTypesetterBehavior_10_2_WithCompatibility;
    if ([self length] > 0) {
        // Checking for empty string is necessary since Layout Manager will give the nominal
        // height of one line if length is 0.  Our API specifies 0.0 for an empty string.
        NSSize size = NSMakeSize(width, height) ;
        NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:size] ;
        NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:self] ;
        NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init] ;
        [layoutManager addTextContainer:textContainer] ;
        [textStorage addLayoutManager:layoutManager] ;
        [layoutManager setHyphenationFactor:0.0] ;
        if (gNSStringGeometricsTypesetterBehavior != NSTypesetterLatestBehavior) {
            [layoutManager setTypesetterBehavior:gNSStringGeometricsTypesetterBehavior] ;
        }
        // NSLayoutManager is lazy, so we need the following kludge to force layout:
        [layoutManager glyphRangeForTextContainer:textContainer] ;

        answer = [layoutManager usedRectForTextContainer:textContainer].size ;
        [textStorage release] ;
        [textContainer release] ;
        [layoutManager release] ;

        // In case we changed it above, set typesetterBehavior back
        // to the default value.
        gNSStringGeometricsTypesetterBehavior = NSTypesetterLatestBehavior ;
    }

    return answer ;
}
4

1 に答える 1

2

これは、あなたが再発明しているように感じます[NSAttributedString boundingRectWithSize:options:](または単にsize)。あなたの実装に何か欠けていますか?NSLayoutManager急速に変化する文字列 (テキスト ビューなど) のレイアウトを処理するためのものです。ほとんどの場合、それはやり過ぎです。あなたは意図的にその最適化をバイパスしています(あなたの行では、それNSLayoutManagerは怠惰であり、最適化されていることを意味します:D)

いずれの場合も、ラッピングの動作を変更するには、NSAttributedStringそれ自体を変更する必要があります。折り返しは段落スタイルの一部です。このようなもの(テストされていない;コンパイルできない可能性があります):

// Lazy here. I'm assuming the entire string has the same style
NSMutableParagraphStyle *style = [[self attribute:NSParagraphStyleAttributeName atIndex:0 effectiveRange:NULL] mutableCopy]; 
[style setLineBreakMode:NSLineBreakByCharWrapping];
NSAttributedString *charWrappedString = [self mutableCopy];
[charWrappedString setAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, [self length]];

NSRect boundingRect = [self boundingRectWithSize:NSMakeSize(width, height) options:0];
NSSize size = boundRect.size;

[style release];
[charWrappedString release];

return size;

スタイルにはいくつかのものが含まれているため、少し注意が必要ですが、すべてをまとめて設定する必要があります。そのため、属性付き文字列に異なるスタイルがあった場合は、文字列をループして、それぞれを処理する必要がありますeffectiveRangeattributesAtIndex:effectiveRange:(との間のトレードオフを理解するには、ドキュメントを読んでくださいattributesAtIndex:longestEffectiveRange:inRange:。)

于 2012-01-21T01:51:35.793 に答える