Align Text Using Drawinrect:Withattributes:

align text using drawInRect:withAttributes:

There is one key to set the paragraph style of the text (including line breaking mode, text alignment, and more).

From docs:

NSParagraphStyleAttributeName

The value of this attribute is an NSParagraphStyle object. Use this attribute to apply multiple attributes to a range of text. If you do not specify this attribute, the string uses the default paragraph attributes, as returned by the defaultParagraphStyle method of NSParagraphStyle.

So, you can try the following:

UIFont *font = [UIFont fontWithName:@"Courier" size:kCellFontSize];

/// Make a copy of the default paragraph style
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
/// Set line break mode
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
/// Set text alignment
paragraphStyle.alignment = NSTextAlignmentRight;

NSDictionary *attributes = @{ NSFontAttributeName: font,
NSParagraphStyleAttributeName: paragraphStyle };

[text drawInRect:rect withAttributes:attributes];

drawInRect: withAttributes text center vertically or put some padding

First you need to calculate the height of the text, with this information and the height of your bounding rectangle, you can easily compute the new rectangle to center the text.

I will share a piece of code I use to center vertically. In my case I use a different drawInRect function (drawInRect:withFont...) and I use sizeWithFont to calculate the size of the text. YOu would either adapt this code to use the functions you're already using (with attributes), or either use the functions I'm posting here.

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

How to use NSString drawInRect to center text?

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

How to set text color when using drawInRect?

You need to set the color of the text in the "attributes" dictionary you pass in via:

[textContent drawInRect: CGRectInset(textRect, 0, 6) withAttributes:attributes];

My suggest would be:

NSDictionary *attributes = @{ NSFontAttributeName:helveticaFont,
NSParagraphStyleAttributeName:paragraphStyle,
NSForegroundColorAttributeName: [NPSColor whiteColor]}

NSString drawInRect:withAttributes: not correctly centered when using NSKernAttributeName

The kerning must be applied only to the first character of each kerning pair.
If you want to display a string with kerning between all n characters then the kerning
attribute must be set for the first n-1 characters.

Instead of:

[text drawInRect:textRect withAttributes:@{NSKernAttributeName: @(self.kerning),
NSForegroundColorAttributeName: textColor,
NSFontAttributeName: font,
NSParagraphStyleAttributeName: paragraphStyle}];

you have to create an attributed string so that you can set the kerning attribute
for a specific range instead of the entire string:

NSMutableAttributedString *as = [[NSMutableAttributedString alloc]
initWithString:text
attributes:@{
NSForegroundColorAttributeName: textColor,
NSFontAttributeName: font,
NSParagraphStyleAttributeName: paragraphStyle}];
[as addAttribute:NSKernAttributeName
value:@(self.kerning)
range:NSMakeRange(0, [text length] - 1)];

[as drawInRect:textRect];

Here the result for the string "1234" and kerning -4.0:

Sample Image

drawInRect text alignment using Swift

NSTextAlignment isn't a valid key. Note how the other keys end in Name. See the docs for NSFontAttributeName and NSForegroundColorAttributeName to see the list of valid keys.

Instead of NSTextAlignment you need to use NSParagraphStyleAttributeName which requires that you create an instance of NSParagraphStyle. That is where you set the alignment to .Center.

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .Center

Draw text with center alignment in Cocoa View

The documentation for -[NSString drawAtPoint:withAttributes:] states the following:

The width (height for vertical layout) of the rendering area is unlimited, unlike drawInRect:withAttributes:, which uses a bounding rectangle. As a result, this method renders the text in a single line.

Since the width is unlimited, that method discards paragraph alignment and always renders the string left-aligned.

You should use -[NSString drawInRect:withAttributes:] instead. Since it accepts a frame and a frame has a width, it can compute center alignments. For instance:

NSMutableParagraphStyle * paragraphStyle =
[[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
[paragraphStyle setAlignment:NSCenterTextAlignment];
NSDictionary * attributes = [NSDictionary dictionaryWithObject:paragraphStyle
forKey:NSParagraphStyleAttributeName];

NSString * mystr = @"this is a long line \n and \n this is also a long line";
NSRect strFrame = { { 20, 20 }, { 200, 200 } };

[mystr drawInRect:strFrame withAttributes:attributes];

Note that you’re leaking paragraphStyle in your original code.

NSString drawInRect:withAttributes: is not drawing text with greater width than the rect in iOS 7.0.3

Try this:

-(void)drawText:(NSString *)string {
// this method must be called after a valid graphic context
// is configured, it can be called in drawRect:, or a bitmap or pdf context is configured.
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);

NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
myFontForContentBold, NSFontAttributeName,
[NSNumber numberWithFloat:1.0], NSBaselineOffsetAttributeName, nil];
NSAttributedString *richText = [[NSAttributedString alloc] initWithString:string attributes:attrsDictionary];

CGRect textRect = [richText boundingRectWithSize:CGSizeMake(400, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
context:nil];

textRect = CGRectMake(130, 80, 400, textRect.size.height);

[richText drawInRect:textRect];
}

If you need to draw large chunk of text, consider Text Kit.

The Text Kit approach:

- (void)drawAddressList:(NSArray *)list atPoint:(CGPoint)point {
NSTextStorage *textStorage = [[NSTextStorage alloc] init];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(400.0f, FLT_MAX)];
[textStorage addLayoutManager:layoutManager];
[layoutManager addTextContainer:textContainer];
textContainer.lineFragmentPadding = 0.0f;

NSDictionary *attributes = @{NSFontAttributeName:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]};
// it's a simple attributes for illustration
for (NSString *address in list) {
NSString *buffer = [NSString stringWithFormat:@"%@\n", address];
[textStorage appendAttributedString:[[NSAttributedString alloc] initWithString:buffer attributes:attributes]];
}

[layoutManager ensureLayoutForTextContainer:textContainer];
CGRect rect = [layoutManager usedRectForTextContainer:textContainer];
rect.size.width = 400.0f;
rect.size.height = ceilf(rect.size.height);
rect.origin = point; // this is the frame needed to draw the address list

[layoutManager drawGlyphsForGlyphRange:NSMakeRange(0, textStorage.length) atPoint:point];
}


Related Topics



Leave a reply



Submit