DrawInRect: с текстовым центром Aтрибутов по вертикали или поместить некоторые дополнения
Я использую drawInRect: withAttributes, чтобы добавить текст в pdf в iOS 7. Мне нужно вертикально центрировать текст внутри CGRect или, по крайней мере, мне нужно сохранить пробел/дополнение между границей CGRect и текстом. В противном случае текст выглядит слишком близко к коробке. Есть ли какой-нибудь атрибут? Если не лучший способ сделать это? Ниже мой код.
Я пробовал NSBaselineOffsetAttributeName, но это только увеличивает разрыв между каждой строкой, но не разрыв с границей прямоугольника.
Благодаря
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(currentContext, bgColor.CGColor);
CGRect renderingRect = CGRectMake(startPoint.x, startPoint.y, width, height);
CGContextFillRect(currentContext, renderingRect);
NSDictionary *attributes = @{ NSFontAttributeName: font,
NSForegroundColorAttributeName: fgColor,
};
[textToDraw drawInRect:renderingRect withAttributes:attributes];
Ответы
Ответ 1
Сначала вам нужно рассчитать высоту текста, используя эту информацию и высоту вашего ограничивающего прямоугольника, вы можете легко вычислить новый прямоугольник, чтобы центрировать текст.
Я поделюсь куском кода, который я использую, чтобы центрировать по вертикали. В моем случае я использую другую функцию drawInRect (drawInRect: withFont...), и я использую sizeWithFont
для вычисления размера текста. Вы бы либо адаптировали этот код для использования функций, которые вы уже используете (с атрибутами), либо используете функции, которые я публикую здесь.
UIFont *font = [UIFont systemFontOfSize:14];
CGSize size = [text sizeWithFont:font];
if (size.width < rect.size.width)
{
CGRect r = CGRectMake(rect.origin.x,
rect.origin.y + (rect.size.height - size.height)/2,
rect.size.width,
(rect.size.height - size.height)/2);
[text drawInRect:r withFont:font lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentLeft];
}
Ответ 2
Вот как это сделать в iOS 8 (или 7+) на основе ответа @Merlevede с исправлением и использованием нового API:
NSString *string = ....
NSDictionary *attributes = ....
CGSize size = [string sizeWithAttributes:attributes];
CGRect r = CGRectMake(rect.origin.x,
rect.origin.y + (rect.size.height - size.height)/2.0,
rect.size.width,
size.height);
[string drawInRect:r withAttributes:attributes];
Ответ 3
Решение Swift 3:
extension NSString {
func drawVerticallyCentered(in rect: CGRect, withAttributes attributes: [String : Any]? = nil) {
let size = self.size(attributes: attributes)
let centeredRect = CGRect(x: rect.origin.x, y: rect.origin.y + (rect.size.height-size.height)/2.0, width: rect.size.width, height: size.height)
self.draw(in: centeredRect, withAttributes: attributes)
}
}
Ответ 4
Быстрая версия в форме расширения на основе ответов @WillLarche и @Merlevede.
extension CGRect {
func verticalCenteredRectForString(string:NSString,withAttributes attributes : [String:AnyObject])->CGRect {
let size = string.sizeWithAttributes(attributes)
return CGRectMake(self.origin.x, self.origin.y + (self.size.height-size.height)/2.0 , self.size.width, size.height)
}
}
Использование
let myString = NSString(string:"Some text")
let centeredRect = customRect.verticalCenteredRectForString(myString,attrParams)
myString.drawInRect(centereRect, withAttributes : attrParams)
P.S.
Я знаю, что имя метода может быть лучше;)
Ответ 5
Решение Swift 4:
extension NSString {
func drawVerticallyCentered(in rect: CGRect, withAttributes attributes: [NSAttributedStringKey : Any]? = nil) {
let size = self.size(withAttributes: attributes)
let centeredRect = CGRect(x: rect.origin.x, y: rect.origin.y + (rect.size.height-size.height)/2.0, width: rect.size.width, height: size.height)
self.draw(in: centeredRect, withAttributes: attributes)
}
}