How to use NSString drawInRect to center text?

Viewed 67794

How can I draw a NSString centered within a NSRect?

I've started off with: (an extract from the drawRect method of my custom view)

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

Now I'm assuming I need to set up some attributes. I've had a look through Apple's Cocoa documentation, but it's a bit overwhelming and can't find anything for how to add paragraph styles to the attributes.

Also, I can only find horizontal alignment, what about vertical alignment?

10 Answers

Vertical alignment you'll have to do yourself ((height of view + height of string)/2). Horizontal alignment you can do with:

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

Martins answer is pretty close, but it has a few small errors. Try this:

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

You'll have to create a new NSMutableParagraphStyle (instead of using the default paragraph style as Martin suggested) because [NSMutableParagraphStyle defaultParagraphStyle] returns an NSParagraphStyle, which doesn't have the setAlignment method. Also, you don't need the string @"NSParagraphStyleAttributeName"—just NSParagraphStyleAttributeName.

This works for me:

    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] won't work use:

[NSMutableParagraphStyle new]

also, it appears horizontal alignment only works for drawInRect, not drawAtPoint (ask me how I know :-)

For iOS Swift, To center String within the rectangle using the method draw(in:withAttributes:)

func drawInCenter(_ text: String, into rectangle: CGRect, with textFont: UIFont) {
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = .center
    let rectangle = CGRect.zero
    paragraphStyle.minimumLineHeight = rectangle.height / 2 + textFont.lineHeight / 2
    let textAttributes = [NSAttributedString.Key.font: textFont,
                          NSAttributedString.Key.paragraphStyle: paragraphStyle] as [NSAttributedString.Key : Any]
    (text as NSString).draw(in: rectangle, withAttributes: textAttributes)
}

Well, drawInRect is only good for basic text drawing (in other words, the system decides where to position your text) - often the only way to draw text positioned where you want is to simply calculate what point you want it at and use NSString's drawAtPoint:withAttributes:.

Also, NSString's sizeWithAttributes is hugely useful in any positioning math you end up having to do for drawAtPoint.

Good luck!

Related