1


リッチ テキストを描画し、さまざまなパラメーターを設定できるカスタム ラベル サブクラスを作成しようとしています。私が持っている最も大きな要求の 1 つは改行についてです。UILabel では修正されており、グラフィック要件に合わない場合があります。
したがって、Apple サイトの小さなスニペットで自分自身を助け、独自のクラスを書き始めましたが、(何とか) 動作しますが、1 つの問題があります。

  1. 行が 1 つだけの場合、テキストは垂直方向に整列されず、常に画面の左上から始まります。

これまでに書いたコードは次のとおりです。

- (void)drawRect:(CGRect)rect
{
    if (_text) {

        if (!_attribstring) {
            [self createAttributedString];
        }
        if (self.lineBreakValue == 0) {
            self.lineBreakValue = 9;
        }

        CGContextRef ctx = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(ctx, 0, self.bounds.size.height);
        CGContextScaleCTM(ctx, 1.0, -1.0); 
        CGContextSetShouldSmoothFonts(ctx, YES);
        CGContextSetShouldAntialias(ctx, YES);
        CGRect textRect = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);

        //Manual Line braking
        BOOL shouldDrawAnotherLine = YES;
        double width = textRect.size.width;
        CGPoint textPosition = CGPointMake(textRect.origin.x, textRect.origin.y+textRect.size.height-self.lineBreakValue);
        ;
        // Initialize those variables.

        // Create a typesetter using the attributed string.
        CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString((__bridge CFAttributedStringRef )  self.attribstring);

        // Find a break for line from the beginning of the string to the given width.
        CFIndex start = 0;
        while (shouldDrawAnotherLine) {

            CFIndex count = CTTypesetterSuggestLineBreak(typesetter, start, width);

            // Use the returned character count (to the break) to create the line.
            CTLineRef line = CTTypesetterCreateLine(typesetter, CFRangeMake(start, count));

            // Get the offset needed to center the line.
            float flush = 0.5; // centered
            double penOffset = CTLineGetPenOffsetForFlush(line, flush, width);

            // Move the given text drawing position by the calculated offset and draw the line.
            CGContextSetTextPosition(ctx, textPosition.x + penOffset, textPosition.y);
            CTLineDraw(line, ctx);
            if (line!=NULL) {
                CFRelease(line);
            }
            // Move the index beyond the line break.

            if (start + count >= [self.attribstring.string length]) {
                shouldDrawAnotherLine = NO;
                continue;
            }
            start += count;
            textPosition.y-=self.lineBreakValue;
        }
        if (typesetter!=NULL) {
            CFRelease(typesetter);

        }

    }

}

誰かが私を正しい方向に向けることができますか? よろしく、
アンドレア

4

1 に答える 1

1

テキストを垂直に並べてレイアウトするには、行の合計の高さを知る必要がありy position、最初の行の高さは次のようになります。

(self.bounds.size.height - (totalLineHeight)) / 2 - font.ascent;

したがって、コードには2つのループが必要です。1つは線の合計の高さを計算するためのものであり(各線の文字数を保存して、後で描画するための別のループで使用することもできます)、もう1つはy position、上記の式。

注:各行の高さはフォントサイズにすることができます。行間に行間隔を追加することもできます。必要なのは、行の高さの計算と、に関する線の描画に一貫性があることだけですy position

于 2012-05-18T01:33:24.657 に答える