iPhone - 如何在矩形中间绘制文本

时间:2009-08-19 21:52:17

标签: iphone

是否有方法在矩形的中间绘制文本。我可以找到各种对齐方式,但我尝试过的任何内容都不能将文本垂直居中于矩形。

有没有一种简单的方法可以做到这一点,或者是否有某种方法可以使矩形居中然后绘制?

我正在直接绘制CGContext,试图使用NSString :: drawWithRect或类似的东西,因为我真的不想添加一个Label来呈现一些基本文本。

6 个答案:

答案 0 :(得分:32)

嗯,字体属性pointSize直接对应于NSString中绘制的UIFont的高度(以像素为单位),因此您的公式将是这样的:

- (void) drawString: (NSString*) s 
           withFont: (UIFont*) font 
             inRect: (CGRect) contextRect {

    CGFloat fontHeight = font.pointSize;
    CGFloat yOffset = (contextRect.size.height - fontHeight) / 2.0;

    CGRect textRect = CGRectMake(0, yOffset, contextRect.size.width, fontHeight);

    [s drawInRect: textRect 
         withFont: font 
    lineBreakMode: UILineBreakModeClip 
        alignment: UITextAlignmentCenter];
}

UITextAlignmentCenter处理horizontal居中,因此我们使用contextRect的全宽。 lineBreakMode可以是您喜欢的任何内容。

答案 1 :(得分:18)

这是iOS7.0 +的更新版本。

我还使用sizeWithAttributes:方法改进了上述答案,该方法返回文本的边界,使您能够在绘制文本之前正确定位文本。这样就无需对任何调整进行硬编码,如果使用不同大小的字体或使用不同的字体,这些调整将会中断。

- (void) drawString: (NSString*) s
           withFont: (UIFont*) font
             inRect: (CGRect) contextRect {

    /// Make a copy of the default paragraph style
    NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    /// Set line break mode
    paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
    /// Set text alignment
    paragraphStyle.alignment = NSTextAlignmentCenter;

    NSDictionary *attributes = @{ NSFontAttributeName: font,
                                  NSForegroundColorAttributeName: [UIColor whiteColor],
                                  NSParagraphStyleAttributeName: paragraphStyle };

    CGSize size = [s sizeWithAttributes:attributes];

    CGRect textRect = CGRectMake(contextRect.origin.x + floorf((contextRect.size.width - size.width) / 2),
                                 contextRect.origin.y + floorf((contextRect.size.height - size.height) / 2),
                                 size.width,
                                 size.height);

    [s drawInRect:textRect withAttributes:attributes];
}

答案 2 :(得分:2)

在iOS 6中,您可以获得归因于字符串和段落对齐的内容,因此这将变得更加直接和强大。在这个例子中,我们在矩形的中间绘制一个大的红色“A”:

NSMutableParagraphStyle* p = [NSMutableParagraphStyle new];
p.alignment = NSTextAlignmentCenter;
NSAttributedString* bigA = 
    [[NSAttributedString alloc] initWithString:@"A" attributes:@{
         NSFontAttributeName: [UIFont fontWithName:@"Georgia" size:100],
         NSForegroundColorAttributeName: [UIColor redColor],
         NSParagraphStyleAttributeName: p
    }];
[bigA drawInRect:CGRectMake(0,0,200,200)];

答案 3 :(得分:2)

Swift 4.2

static func draw(_ text: String, _ rect: CGRect, _ font: UIFont) {

    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = .center
    let attributes = [
        NSAttributedString.Key.paragraphStyle: paragraphStyle,
        NSAttributedString.Key.font: font,
        NSAttributedString.Key.foregroundColor: UIColor.red
    ]
    NSAttributedString(string: text, attributes: attributes).draw(in: rect.insetBy(dx: 0, dy: (rect.height - font.pointSize)/2))
}

答案 4 :(得分:1)

我同意amagrammer的答案,除了一个小改动:我使用font.lineSize来获得适当的高度。我假设sizeWithFont也会给你lineSize

答案 5 :(得分:0)

我发现这段代码效果很好:

NSString *text = @"A bit of text to draw";
UIFont *font = [UIFont systemFontOfSize:12];
CGRect textFrame = (CGRect)
{
    .size.width = 150,
    .size.height = 150,
};
CGSize textSize = [text sizeWithFont:font constrainedToSize:textFrame.size lineBreakMode:NSLineBreakByWordWrapping];
CGRect newTextFrame = CGRectInset(textFrame, 0, (textFrame.size.height - textSize.height) / 2);
[text drawInRect:newTextFrame withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentCenter];

文本,字体和包含框架可以来自任何地方,因此在进行计算和绘图时只需使用相同的换行模式。