Как использовать NSString drawInRect для центрирования текста?
Как я могу нарисовать NSString
в центре NSRect
?
Я начал с: (выдержка из метода drawRect моего пользовательского представления)
NSString* theString = ...
[theString drawInRect:theRect withAttributes:0];
[theString release];
Теперь я предполагаю, что мне нужно настроить некоторые атрибуты. Я просмотрел документацию Apple по Какао, но она немного перегружена и не может найти ничего, как добавить стили абзаца к атрибутам.
Кроме того, я могу найти только горизонтальное выравнивание, а как насчет вертикального выравнивания?
10 ответов
Вертикальное выравнивание вам придется делать самостоятельно ((высота обзора + высота строки)/2). Горизонтальное выравнивание вы можете сделать с помощью:
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
style.alignment = NSTextAlignmentCenter;
NSDictionary *attr = [NSDictionary dictionaryWithObject:style forKey:NSParagraphStyleAttributeName];
[myString drawInRect:someRect withAttributes:attr];
Это работает для меня для горизонтального выравнивания
[textX drawInRect:theRect
withFont:font
lineBreakMode:UILineBreakModeClip
alignment:UITextAlignmentCenter];
Ответ Мартинса довольно близок, но в нем есть несколько мелких ошибок. Попробуй это:
NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init];
[style setAlignment:NSCenterTextAlignment];
NSDictionary *attr =
[NSDictionary dictionaryWithObject:style
forKey:NSParagraphStyleAttributeName];
[myString drawInRect:someRect withAttributes:attr];
[style release];
Вам придется создать новый NSMutableParagraphStyle
(вместо использования стиля абзаца по умолчанию, как предложил Мартин), потому что [NSMutableParagraphStyle defaultParagraphStyle]
возвращает NSParagraphStyle
, который не имеет метода setAlignment. Кроме того, вам не нужна строка @"NSParagraphStyleAttributeName"
-просто NSParagraphStyleAttributeName
,
Это работает для меня:
CGRect viewRect = CGRectMake(x, y, w, h);
UIFont* font = [UIFont systemFontOfSize:15];
CGSize size = [nsText sizeWithFont:font
constrainedToSize:viewRect.size
lineBreakMode:(UILineBreakModeWordWrap)];
float x_pos = (viewRect.size.width - size.width) / 2;
float y_pos = (viewRect.size.height - size.height) /2;
[someText drawAtPoint:CGPointMake(viewRect.origin.x + x_pos, viewRect.origin.y + y_pos) withFont:font];
[NSMutableParagraphStyle defaultParagraphStyle]
не будет работать использовать:
[NSMutableParagraphStyle new]
Кроме того, кажется, что горизонтальное выравнивание работает только для drawInRect
не drawAtPoint
(спросите меня, откуда я знаю:-)
Для всех, кто интересуется адаптацией iOS7+, добавьте это в категорию NSString:
- (void)drawVerticallyInRect:(CGRect)rect withFont:(UIFont *)font color:(UIColor *)color andAlignment:(NSTextAlignment)alignment
{
rect.origin.y = rect.origin.y + ((rect.size.height - [self sizeWithAttributes:@{NSFontAttributeName:font}].height) / 2);
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setAlignment:alignment];
[self drawInRect:rect withAttributes:@{
NSFontAttributeName : font,
NSForegroundColorAttributeName : color,
NSParagraphStyleAttributeName : style
}];
}
Только для iOS Swift 4, чтобы центрировать строку внутри прямоугольника, используя метод draw(in:withAttributes:)
let textFont = UIFont.boldSystemFont(ofSize: )
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
paragraphStyle.minimumLineHeight = rectangle.height / 2 + textFont.lineHeight / 2
let textAttributes = [
NSAttributedStringKey.font: textFont,
NSAttributedStringKey.paragraphStyle: paragraphStyle
] as [NSAttributedStringKey : Any]
let text = "Text"
(text as NSString).draw(in: rectangle, withAttributes: textAttributes)
Ну, drawInRect подходит только для базового рисования текста (другими словами, система решает, где расположить ваш текст) - часто единственный способ нарисовать текст, расположенный там, где вы хотите, это просто вычислить, в какой точке вы хотите его разместить, и использовать drawAtPoint из NSString.:withAttributes:.
Кроме того, sizeWithAttributes NSString чрезвычайно полезен в любой математике позиционирования, которую вам в конечном итоге придется сделать для drawAtPoint.
Удачи!
Правильный ответ:
-drawInRect:withFont:lineBreakMode:alignment:
Я также создал небольшую категорию для вертикального выравнивания. Если вам нравится использовать его, продолжайте:)
// NSString+NSVerticalAlign.h
typedef enum {
NSVerticalTextAlignmentTop,
NSVerticalTextAlignmentMiddle,
NSVerticalTextAlignmentBottom
} NSVerticalTextAlignment;
@interface NSString (VerticalAlign)
- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font verticalAlignment:(NSVerticalTextAlignment)vAlign;
- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(NSLineBreakMode)lineBreakMode verticalAlignment:(NSVerticalTextAlignment)vAlign;
- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(NSLineBreakMode)lineBreakMode alignment:(NSTextAlignment)alignment verticalAlignment:(NSVerticalTextAlignment)vAlign;
@end
// NSString+NSVerticalAlign.m
#import "NSString+NSVerticalAlign.h"
@implementation NSString (VerticalAlign)
- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font verticalAlignment:(NSVerticalTextAlignment)vAlign {
switch (vAlign) {
case NSVerticalTextAlignmentTop:
break;
case NSVerticalTextAlignmentMiddle:
rect.origin.y = rect.origin.y + ((rect.size.height - font.pointSize) / 2);
break;
case NSVerticalTextAlignmentBottom:
rect.origin.y = rect.origin.y + rect.size.height - font.pointSize;
break;
}
return [self drawInRect:rect withFont:font];
}
- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(NSLineBreakMode)lineBreakMode verticalAlignment:(NSVerticalTextAlignment)vAlign {
switch (vAlign) {
case NSVerticalTextAlignmentTop:
break;
case NSVerticalTextAlignmentMiddle:
rect.origin.y = rect.origin.y + ((rect.size.height - font.pointSize) / 2);
break;
case NSVerticalTextAlignmentBottom:
rect.origin.y = rect.origin.y + rect.size.height - font.pointSize;
break;
}
return [self drawInRect:rect withFont:font lineBreakMode:lineBreakMode];
}
- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(NSLineBreakMode)lineBreakMode alignment:(NSTextAlignment)alignment verticalAlignment:(NSVerticalTextAlignment)vAlign {
switch (vAlign) {
case NSVerticalTextAlignmentTop:
break;
case NSVerticalTextAlignmentMiddle:
rect.origin.y = rect.origin.y + ((rect.size.height - font.pointSize) / 2);
break;
case NSVerticalTextAlignmentBottom:
rect.origin.y = rect.origin.y + rect.size.height - font.pointSize;
break;
}
return [self drawInRect:rect withFont:font lineBreakMode:lineBreakMode alignment:alignment];
}
@end
Следующий фрагмент полезен для рисования центральной текстовой строки с использованием пользовательского изображения Annotation в качестве ссылки:
CustomAnnotation.h
@interface CustomAnnotation : MKAnnotationView
[...]
CustomAnnotation.m
[...]
- (void)drawRect:(CGRect)rect
{
ClusterAnnotation *associatedAnnotation = (CustomAnnotation *)self.annotation;
if (associatedAnnotation != nil)
{
CGContextRef context = UIGraphicsGetCurrentContext();
NSString *imageName = @"custom_image.png";
CGRect contextRect = CGRectMake(0, 0, 42.0, 42.0);
CGFloat fontSize = 14.0;
[[UIImage imageNamed:imageName] drawInRect:contextRect];
NSInteger myIntegerValue = [associatedAnnotation.dataObject.myIntegerValue integerValue];
NSString *myStringText = [NSString stringWithFormat:@"%d", myIntegerValue];
UIFont *font = [UIFont fontWithName:@"Helvetica-Bold" size:fontSize];
CGSize fontWidth = [myStringText sizeWithFont:font];
CGFloat yOffset = (contextRect.size.height - fontWidth.height) / 2.0;
CGFloat xOffset = (contextRect.size.width - fontWidth.width) / 2.0;
CGPoint textPoint = CGPointMake(contextRect.origin.x + xOffset, contextRect.origin.y + yOffset);
CGContextSetTextDrawingMode(context, kCGTextStroke);
CGContextSetLineWidth(context, fontSize/10);
CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);
[myStringText drawAtPoint:textPoint withFont:font];
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSetFillColorWithColor(context, [[UIColor blackColor] CGColor]);
[myStringText drawAtPoint:textPoint withFont:font];
}
}