align text using drawInRect:withAttributes: - ios

In the iOS 5 version of my app I had:
[self.text drawInRect: stringRect
withFont: [UIFont fontWithName: #"Courier" size: kCellFontSize]
lineBreakMode: NSLineBreakByTruncatingTail
alignment: NSTextAlignmentRight];
I'm upgrading for iOS 7. The above method is deprecated. I'm now using drawInRect:withAttributes:. The attributes parameter is an NSDictionary object. I can get drawInRect:withAttributes: to work for the former font parameter using this:
UIFont *font = [UIFont fontWithName: #"Courier" size: kCellFontSize];
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys: font, NSFontAttributeName,
nil];
[self.text drawInRect: stringRect
withAttributes: dictionary];
What key-value pairs do I add to dictionary to get NSLineBreakByTruncatingTail and NSTextAlignmentRight?

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

The code is going that way:
CGRect textRect = CGRectMake(x, y, length-x, maxFontSize);
UIFont *font = [UIFont fontWithName:#"Courier" size:maxFontSize];
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
paragraphStyle.alignment = NSTextAlignmentRight;
NSDictionary *attributes = #{ NSFontAttributeName: font,
NSParagraphStyleAttributeName: paragraphStyle,
NSForegroundColorAttributeName: [UIColor whiteColor]};
[text drawInRect:textRect withAttributes:attributes];

Related

Have multiple ranges with different attributes on NSAttributedString

I have a multiline UILabel of which I would like to increase the line height, but I also want part of it to be a different color, only the line height works fine. But as soon as I try to change the color for a certain range it just goes back to the stock appearance, no line either..
Anyone a tip? This is done in the content setter.
- (void)setContent:(NSString *)content {
_content = content;
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:self.content];
NSMutableAttributedString *mutableAttrString = [attributedString mutableCopy];
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paragraphStyle setLineSpacing: 5.0f];
NSDictionary *attributes = #{
NSFontAttributeName: [UIFont fontWithName:#"BentonSans-Regular" size:16.0],
NSParagraphStyleAttributeName: paragraphStyle
};
NSDictionary *colorAttributes = #{
NSForegroundColorAttributeName: [UIColor redColor]
};
[mutableAttrString addAttributes:attributes range:NSRangeFromString(self.content)];
[mutableAttrString addAttributes:colorAttributes range:NSMakeRange(4, 8)];
[self.label setAttributedText: mutableAttrString];
}
Thanks!
The NSRangeFromString function expects a string like #"{3,10}". In other words, it expects a string that contains two numbers that specify the starting location and length of the range. I suspect that the content string isn't a string like that.
So this line
[mutableAttrString addAttributes:attributes range:NSRangeFromString(self.content)];
should be
[mutableAttrString addAttributes:attributes range:NSMakeRange(0,mutableAttrString.length)];
in your viewdidLoad Method assign string to self.content :
self.content = #"pass your text ";
// Remove the First line of your method it is not needed
- (void)setContent:(NSString *)content {
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:self.content];
NSMutableAttributedString *mutableAttrString = [attributedString mutableCopy];
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paragraphStyle setLineSpacing: 5.0f];
NSDictionary *attributes = #{
NSFontAttributeName: [UIFont fontWithName:#"BentonSans-Regular" size:16.0],
NSParagraphStyleAttributeName: paragraphStyle
};
NSDictionary *colorAttributes = #{
NSForegroundColorAttributeName: [UIColor redColor]
};
[mutableAttrString addAttributes:attributes range:NSRangeFromString(self.content)];
[mutableAttrString addAttributes:colorAttributes range:NSMakeRange(4, 8)];
[self.label setAttributedText: mutableAttrString];
}

Intrinsic content size of UILabel with NSAttributedString and indentation

Why does setting an indent on the paragraph style attribute not have an affect on a UILabel using NSAttributedString?
For example:
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.firstLineHeadIndent = 50;
NSDictionary *attributes = #{
NSForegroundColorAttributeName : [UIColor redColor],
NSParagraphStyleAttributeName : paragraphStyle,
};
NSString *string = #"some string";
self.label.attributedText = [[NSAttributedString alloc] initWithString:string
attributes:attributes];
UILabel with indentation (green background set to see the label size):
UILabel without indentation (green background set to see the label size):

How can I show the text with different fonts in textView in ios?

Hi I am doing one application. In that I need to show text in different fonts. I mean if I show name in one font and I show city name in different font.
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(50, 50, 200, 100)];
textView.text = #"Vijay Apple Dev";
NSString *textViewText = textView.text;
NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:textViewText];
[attributedText addAttribute:NSFontAttributeName
value:[UIFont fontWithName:#"Courier" size:20]
range:[textViewText rangeOfString:#"Apple"]];
[attributedText addAttribute:NSFontAttributeName
value:[UIFont fontWithName:#"Verdana" size:20]
range:[textViewText rangeOfString:#"Vijay"]];
textView.attributedText = attributedText;
[self.view addSubview:textView];
Try to do like this one... And customize according to your requirement like font name and font size
NSString *firstName = #"FirstName";
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:firstName];
UIFont *font = [UIFont fontWithName:#"Helvetica" size:20];
[attributedString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, firstName.length)];// Here define your range.
textView.attributedText = attributedString;
//Use attributed String
//Apply properties to both strings
//then merge and set it to textview
NSString *selectedString=#"Hey,";
UIFont *fontSelectedText = [UIFont boldSystemFontOfSize:25];
NSDictionary *dictBoldSelectedText = [NSDictionary dictionaryWithObjectsAndKeys:fontSelectedText, NSFontAttributeName, nil];
NSMutableAttributedString *mutAttrTextViewSelectedString = [[NSMutableAttributedString alloc] initWithString:selectedString];
[mutAttrTextViewSelectedString setAttributes:dictBoldSelectedText range:NSMakeRange(0,selectedString.length)];
[_tTextView setAttributedText:mutAttrTextViewSelectedString];
//Second String
NSString *restOfStrig=#"\nHello";
NSMutableAttributedString *mutAttrTextViewString = [[NSMutableAttributedString alloc] initWithString:restOfStrig];
UIFont *fontText = [UIFont boldSystemFontOfSize:16];
NSDictionary *dictBoldText = [NSDictionary dictionaryWithObjectsAndKeys:fontText, NSFontAttributeName, nil];
[mutAttrTextViewString setAttributes:dictBoldText range:NSMakeRange(0,restOfStrig.length)];
//Combining both the Attributed String
[mutAttrTextViewSelectedString appendAttributedString:mutAttrTextViewString];
NSMutableAttributedString * finalAttributedStr=[[NSMutableAttributedString alloc] initWithAttributedString:mutAttrTextViewSelectedString];
//setting it to the textView
[_tTextView setAttributedText:finalAttributedStr];
Use NSAttributedString
An NSAttributedString object manages character strings and associated sets of attributes (for example, font and kerning) that apply to individual characters or ranges of characters in the string. An association of characters and their attributes is called an attributed string. The cluster’s two public classes, NSAttributedString and NSMutableAttributedString, declare the programmatic interface for read-only attributed strings and modifiable attributed strings, respectively.
NSAttributedString
When you create your attributed string, then just set it to your textView:
self.textView.attributedText = myAttributedString;

Is is possible to format a specific part of an string within objective-c?

Is it possible to format a section of text in a string within the actual code of xcode to be displayed in a single label? For instance make a specific word bold while leaving the rest normal.
Or do I have to use separate strings with different labels with the specific formatting already determined?
Use attributed text. Example below bolds the word posted By but not the name
NSString *format = NSLocalizedStringFromTable(#"Posted By: %#", #"Details Screen", #"posted by %#");
NSString *text = [NSString stringWithFormat:format, name];
const CGFloat fontSize = 14.0;
UIFont *boldFont = [UIFont fontWithName:#"HelveticaNeue-Bold" size:fontSize];
UIFont *regularFont = [UIFont fontWithName:#"HelveticaNeue" size:fontSize];
UIColor *foregroundColor = [UIColor colorWithWhite:(51.0/255.0) alpha:1.0];
// Create the attributes
NSDictionary *attrs = #{NSFontAttributeName: boldFont,
NSForegroundColorAttributeName: foregroundColor};
NSDictionary *subAttrs = #{NSFontAttributeName: regularFont};
const NSRange range = NSMakeRange(text.length - name.length,name.length); // range of " Posted by: "
// Create the attributed string (text + attributes)
NSMutableAttributedString *attributedText =
[[NSMutableAttributedString alloc] initWithString:text
attributes:attrs];
[attributedText setAttributes:subAttrs range:range];
// Set it in our UILabel and we are done!
[_textLabel setAttributedText:attributedText];

What is the equivalent of NSLineBreakMode in iOS 7 attributed strings drawing methods?

There was a method
- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(NSLineBreakMode)lineBreakMode alignment:(NSTextAlignment)alignment;
which I must replace now for iOS 7. I get as far as
NSDictionary *attributes = #{NSFontAttributeName: font};
[self drawInRect:rect withAttributes:attributes];
but how to specify the line break mode like word wrap? I searched documentation of Attributed string drawing symbols but no mention of line break mode. Is this automartically always word-wrap?
You need to create a paragraph style.
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setLineBreakMode:NSLineBreakByWordWrapping];
NSDictionary *attributes = #{NSFontAttributeName: font, NSParagraphStyleAttributeName: style};
[self drawInRect:rect withAttributes:attributes];
More information here:
https://developer.apple.com/documentation/uikit/nsparagraphstyle?language=objc
In Swift 5:
let style = NSMutableParagraphStyle()
style.lineBreakMode = .byWordWrapping
let attributes: [NSAttributedString.Key: Any] = [
.font: font,
.paragraphStyle: style
]

Resources