it-swarm.com.ru

Как использовать NSString drawInRect для центрирования текста?

Как я могу нарисовать NSString с центром в NSRect?

Я начал с: (выдержка из метода drawRect моего пользовательского представления)

NSString* theString = ...
[theString drawInRect:theRect withAttributes:0];
[theString release];

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

Кроме того, я могу найти только горизонтальный выравнивание, а как насчет вертикальный выравнивание?

40
Steve Folly

Вертикальное выравнивание вам придется делать самостоятельно ((высота обзора + высота строки)/2). Горизонтальное выравнивание вы можете сделать с помощью:

NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
style.alignment = NSTextAlignmentCenter;
NSDictionary *attr = [NSDictionary dictionaryWithObject:style forKey:NSParagraphStyleAttributeName];
[myString drawInRect:someRect withAttributes:attr];
90
Martin Pilkington

Это работает для меня для горизонтального выравнивания

[textX drawInRect:theRect 
         withFont:font 
    lineBreakMode:UILineBreakModeClip 
        alignment:UITextAlignmentCenter];
27
Nikolay Klimchuk

Ответ Мартинса довольно близок, но в нем есть несколько мелких ошибок. Попробуй это:

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.

19
matthewwithanm

Это работает для меня:

    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];
12
Dorin Grecu

[NSMutableParagraphStyle defaultParagraphStyle] не будет работать использовать:

[NSMutableParagraphStyle new]

кроме того, кажется, что горизонтальное выравнивание работает только для drawInRect, а не drawAtPoint (спросите меня, откуда я знаю :-)

4
David H

Для всех, кто интересуется адаптацией 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
                                       }];
}
4
Kris

Ну, drawInRect подходит только для базового рисования текста (другими словами, система решает, где расположить ваш текст) - часто единственный способ нарисовать текст, расположенный там, где вы хотите, это просто вычислить, в какой точке вы хотите его разместить, и использовать drawAtPoint из NSString. : withAttributes :.

Кроме того, sizeWithAttributes NSString чрезвычайно полезен в любой математике позиционирования, которую вам в конечном итоге придется сделать для drawAtPoint.

Удачи!

2
Joel Levin

Только для 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)
1
Malder

Правильный ответ:

-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
1
Julian F. Weinert

Следующий фрагмент полезен для рисования центральной текстовой строки с использованием пользовательского изображения 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];


            }
        }
0
jalopezsuarez