如何使用NSString drawInRect来居中文本?

时间:2009-01-25 10:34:33

标签: objective-c cocoa macos

如何在NSString?{/ p>中画出NSRect

我开始使用:(来自我的自定义视图的drawRect方法的摘录)

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

现在我假设我需要设置一些属性。我已经浏览了Apple的Cocoa文档,但它有点压倒性,无法找到有关如何为属性添加段落样式的任何内容。

另外,我只能找到水平对齐,垂直对齐怎么办?

10 个答案:

答案 0 :(得分:90)

您必须自己进行垂直对齐((视图高度+字符串高度)/ 2)。您可以使用水平对齐:

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

答案 1 :(得分:27)

这适合我进行水平对齐

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

答案 2 :(得分:19)

马丁斯的答案非常接近,但它有一些小错误。试试这个:

NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init];
[style setAlignment:NSCenterTextAlignment];
NSDictionary *attr = 
  [NSDictionary dictionaryWithObject:style 
                              forKey:NSParagraphStyleAttributeName];
[myString drawInRect:someRect withAttributes:attr];
[style release];

您必须创建一个新的NSMutableParagraphStyle(而不是像Martin建议的那样使用默认的段落样式),因为[NSMutableParagraphStyle defaultParagraphStyle]返回NSParagraphStyle,它没有setAlignment方法。此外,您不需要字符串@"NSParagraphStyleAttributeName" - 只需NSParagraphStyleAttributeName

答案 3 :(得分:12)

这对我有用:

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

答案 4 :(得分:4)

[NSMutableParagraphStyle defaultParagraphStyle]无法使用:

[NSMutableParagraphStyle new]

另外,它似乎水平对齐仅适用于drawInRect,而不是drawAtPoint(问我怎么知道: - )

答案 5 :(得分:4)

对于对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
                                       }];
}

答案 6 :(得分:2)

嗯,drawInRect只适用于基本文本绘制(换句话说,系统决定文本的位置) - 通常只能在你想要的位置绘制文本的方法是简单地计算你想要它的点和使用NSString的drawAtPoint:withAttributes:。

另外,NSString的sizeWithAttributes在你最终必须为drawAtPoint做的任何定位数学中都非常有用。

祝你好运!

答案 7 :(得分:2)

仅适用于 iOS Swift 4 , 使用方法 draw(in:withAttributes :)

将字符串置于矩形中心
ERROR:  The column ProjectReferenceDataLibrary_BaseUnit.ContextLink 
does not exist
LINE 1218:         COALESCE("ProjectReferenceDataLibrary_BaseUnit"."Con...
                        ^
SQL state: 42703
Character: 74151

    -- Create link table for class ProjectReferenceDataLibrary
CREATE TABLE "Directory"."ProjectReferenceDataLibrary_BaseUnit" (
    "ContextLink" varchar NOT NULL,
    "ProjectReferenceDataLibrary" uuid NOT NULL,
    "BaseUnit" uuid NOT NULL
);

-- Create link table for class ProjectReferenceDataLibrary
CREATE TABLE "Directory"."ProjectReferenceDataLibrary_BaseQuantityKind" (
    "ContextLink" text NOT NULL,
    "ProjectReferenceDataLibrary" uuid NOT NULL,
    "BaseQuantityKind" uuid NOT NULL,
    "OrderKey" bigint NOT NULL
);  

CREATE VIEW "Directory"."ProjectReferenceDataLibrary_View" AS
    SELECT "ProjectReferenceDataLibrary"."UniqueIdentifier", "ProjectReferenceDataLibrary"."ValueTypeDictionary" AS "ValueTypeSet",
        "ProjectReferenceDataLibrary"."Container",
        COALESCE("ProjectReferenceDataLibrary_BaseUnit"."BaseUnit",'{}'::text[]) AS "BaseUnit",
        COALESCE("ProjectReferenceDataLibrary_BaseUnit"."ContextLink",'{}'::text[]) AS "BaseUnit_ContextLink",
        COALESCE("ProjectReferenceDataLibrary_BaseQuantityKind"."BaseQuantityKind",'{}'::text[]) AS "BaseQuantityKind",
        COALESCE("ProjectReferenceDataLibrary_BaseQuantityKind"."ContextLink",'{}'::text[]) AS "BaseQuantityKind_ContextLink"
FROM "Directory"."ProjectReferenceDataLibrary" AS "ProjectReferenceDataLibrary"
LEFT JOIN (SELECT "ProjectReferenceDataLibrary" AS "UniqueIdentifier", array_agg("BaseUnit"::text) AS "BaseUnit", array_agg("ContextLink"::text) AS "BaseUnit_ContextLink"
    FROM "Directory"."ProjectReferenceDataLibrary_BaseUnit"
    JOIN "Directory"."ProjectReferenceDataLibrary" AS "ProjectReferenceDataLibrary" ON "ProjectReferenceDataLibrary" = "UniqueIdentifier"
    GROUP BY "ProjectReferenceDataLibrary") AS "ProjectReferenceDataLibrary_BaseUnit" USING ("UniqueIdentifier")
LEFT JOIN (SELECT "ProjectReferenceDataLibrary" AS "UniqueIdentifier", ARRAY[array_agg("OrderKey"::text), array_agg("BaseQuantityKind"::text)] AS "BaseQuantityKind", array_agg("ContextLink"::text) AS "BaseQuantityKind_ContextLink"
    FROM "Directory"."ProjectReferenceDataLibrary_BaseQuantityKind"
    JOIN "Directory"."ProjectReferenceDataLibrary" AS "ProjectReferenceDataLibrary" ON "ProjectReferenceDataLibrary" = "UniqueIdentifier"
    GROUP BY "ProjectReferenceDataLibrary") AS "ProjectReferenceDataLibrary_BaseQuantityKind" USING ("UniqueIdentifier");

答案 8 :(得分:1)

正确答案是:

-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

答案 9 :(得分:0)

以下代码段对于使用“注释”自定义图像作为参考来绘制中心文本字符串非常有用:

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


            }
        }