iPhone - Как нарисовать текст в середине прямоугольника - PullRequest
19 голосов
/ 20 августа 2009

Есть ли способ рисовать текст в середине прямоугольника. Я могу найти различные выравнивания, но ничто из того, что я пробовал, не может вертикально отцентрировать текст в прямоугольнике.

Есть ли простой способ сделать это, или есть какой-то способ отцентрировать прямоугольник и затем нарисовать в нем?

Я рисую прямо в CGContext, пытаясь использовать NSString :: drawWithRect или что-то подобное, поскольку я действительно не хочу добавлять метку только для визуализации некоторого основного текста.

Ответы [ 6 ]

32 голосов
/ 20 августа 2009

Ну, свойство шрифта 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 может быть чем угодно.

18 голосов
/ 23 сентября 2014

Вот обновленная версия для 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 голосов
/ 29 октября 2018

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))
}
2 голосов
/ 24 октября 2012

В iOS 6 вы получаете атрибуты строк и выравнивания абзацев, так что это становится намного более простым и мощным. В этом примере мы рисуем большую красную букву «А» в середине прямоугольника:

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)];
1 голос
/ 08 декабря 2012

Я согласен с ответом amagrammer, за исключением небольшого изменения: я использую font.lineSize для получения нужной высоты Я предполагаю, что sizeWithFont даст вам также размер строки

0 голосов
/ 05 июня 2013

Я обнаружил, что этот код работает довольно хорошо:

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];

Текст, шрифт и содержащий фрейм могут поступать откуда угодно, поэтому просто используйте тот же режим разрыва строки при выполнении расчетов и рисования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...