Iphone CoreText手动换行:如何定位文本,垂直对齐?

Iphone CoreText手动换行:如何定位文本,垂直对齐?,iphone,ios,uilabel,core-text,Iphone,Ios,Uilabel,Core Text,我正在尝试创建一个自定义标签子类,它可以绘制富文本,并且可以在其中设置不同的参数。我有一个最大的要求是关于断线。在UILabel中,标签是固定的,有时不符合图形要求。 因此,我在苹果网站上帮自己写了一个小片段,我开始编写自己的类,它(不知怎么的)起作用了,但我有一个问题: 如果该行只有一行,则文本没有垂直对齐,它总是从屏幕左上角开始 以下是我迄今为止编写的代码: - (void)drawRect:(CGRect)rect { if (_text) { if (!_att


我正在尝试创建一个自定义标签子类,它可以绘制富文本,并且可以在其中设置不同的参数。我有一个最大的要求是关于断线。在UILabel中,标签是固定的,有时不符合图形要求。
因此,我在苹果网站上帮自己写了一个小片段,我开始编写自己的类,它(不知怎么的)起作用了,但我有一个问题:

  • 如果该行只有一行,则文本没有垂直对齐,它总是从屏幕左上角开始
  • 以下是我迄今为止编写的代码:

    - (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);
    
            }
    
        }
    
    }
    
    有人能给我指一下正确的方向吗? 问候,

    Andrea

    对于垂直对齐的文本布局,您需要知道行的总高度,第一行的
    y位置将是:

    (self.bounds.size.height - (totalLineHeight)) / 2 - font.ascent;
    
    因此,您的代码中需要两个循环,一个用于计算线条的总高度(您还可以保存每条线条的字符数,以便以后在另一个用于绘制的循环中使用),另一个用于从使用上述公式计算的
    y位置开始绘制线条


    注意:每行的高度可以是字体大小,您也可以在行之间添加行距,您需要确保的是,在计算行距和绘制与
    y位置有关的行时保持一致,对于垂直对齐的文本布局,您需要知道行的总高度,第一行的
    y位置将是:

    (self.bounds.size.height - (totalLineHeight)) / 2 - font.ascent;
    
    因此,您的代码中需要两个循环,一个用于计算线条的总高度(您还可以保存每条线条的字符数,以便以后在另一个用于绘制的循环中使用),另一个用于从使用上述公式计算的
    y位置开始绘制线条


    注意:每行的高度可以是字体大小,您也可以在行之间添加行距,您只需确保在计算行距和绘制那些与
    y位置有关的行时保持一致

    谢谢,尼维克,我来试试。谢谢,尼维克,我来试试。