NSMutableAttributedString crashes when changing fonts for different ranges - ios

So I'm trying to change the colors of a NSMutableAttributedString but I keep getting an out of bounds exception error when I try to add multiple ranges (see below). If on the other hand I just do a single range from 0 to totalLength-1, there is no issue. I don't know why this is happening.
My code is below:
NSString *testString = #"This is my test string for this example";
NSMutableAttributedString *attribString = [[NSMutableAttributedString alloc] initWithString:testString];
int totalLength = [playerTurnString length];
[playerTurnString addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor] range:NSMakeRange(0, 11)];
[playerTurnString addAttribute:NSForegroundColorAttributeName
value:[UIColor blueColor] range:NSMakeRange(12, totalLength-1)];

An NSRange is a location and a length, so when you do
NSMakeRange(12, totalLength-1)
Your length is 12 too long and therefore exceeds the range of the string. You're trying to use it as a start and end location but that isn't how it works.

Related

Find last line of multiline label and change colour [duplicate]

This question already has answers here:
UILabel Text with Multiple Font Colors
(8 answers)
Closed 4 years ago.
I m working on multi line text with different colour.The following code to change the first line colour But want to change the last line colour.
NSRange rangeOfNewLine = [label.text rangeOfString:#"\n"];
NSRange newRange = NSMakeRange(0, rangeOfNewLine.location);
[text addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:newRange];
NSArray* lines = [label.text componentsSeparatedByString:#"\n"];
NSString* lastLine = lines.lastObject;
NSRange rangeOfLastLine = [label.text rangeOfString:lastLine];
[text addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:rangeOfLastLine];
//NSString *myString = #"I have to replace text 'Dr Andrew Murphy, John Smith' ";
NSString *myString = #"Not a member?signin";
//Create mutable string from original one
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:myString];
//Fing range of the string you want to change colour
attributeText _label.attributedText = attString;
//If you need to change colour in more that one place just repeat it
NSRange range = [myString rangeOfString:#"signin"];
[attString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:(63/255.0) green:(163/255.0) blue:(158/255.0) alpha:1.0] range:range];
//Add it to the label - notice its not text property but it's
attributeText _label.attributedText = attString;

add bold text between text in UILabel [duplicate]

This question already has answers here:
How do you use NSAttributedString?
(15 answers)
Closed 7 years ago.
I to display long text with too much modification..
Large text contains special characters. Whenever special character occur below line should be bold and on occur of \n new label should generated.
Try This : you can add any font style in value parameter.Using this you can add style to substring to make it different from normal string.
NSString *strFirst = #"Anylengthtext";
NSString *strSecond = #"Anylengthtext";
NSString *strThird = #"Anylengthtext";
NSString *strComplete = [NSString stringWithFormat:#"%# %# %#",strFirst,strSecond,strThird];
NSMutableAttributedString *attributedString =[[NSMutableAttributedString alloc] initWithString:strComplete];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor whiteColor]
range:[strComplete rangeOfString:strFirst]];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIFont fontWithName:#"Roboto-Regular" size:12]
range:[strComplete rangeOfString:strSecond]];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor blueColor]
range:[strComplete rangeOfString:strThird]];
self.lblName.attributedText = attributedString;

Display string having words with multiple formatting

In my app, I am displaying user comment that is fetched from the server. The comment contains user name, tag and some text in bold.
For example:
"Nancy tagged Clothing: Season 2, Episode 5. where do they find all the old clothes"
The words "Nancy" and "Clothing:" should be gray and orange color, respectively and "Season 2, Episode 5." should be bold.
I have tried using NSAttributedString but failed to achieve the above.
Following is the code I tried to change color but nothing changed. I am not very sure of how to use NSAttributedString.
NSMutableAttributedString *title = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:#"%#:", tag.title]];
[title addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:246/255.0 green:139/255.0 blue:5/255.0 alpha:1.0f] range:NSMakeRange(0,[title length])];
self.tagCommentLabel.text = [NSString stringWithFormat:#"%# tagged %#: %# %#",tag.user.name , title, episode, tag.comment];
Can someone help me with a code as to how can I achieve the example sentence with the desired formatting?
NSAttributedString and NSString are two different things. If you want to add attributes to NSString (e.g. change the color of the text), you have to first make the NSString:
NSString *string = [NSString stringWithFormat:#"%# tagged %#: %# %#",tag.user.name , title, episode, tag.comment];
Then you make NSMutableAttributedString from your NSString and add attributes to it:
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:string];
[attString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:246/255.0 green:139/255.0 blue:5/255.0 alpha:1.0f] range:[string rangeOfString:title];
And when you want to display your attributed string, you should use .attributedText instead of .text:
self.tagCommentLabel.attributedText = attString;
You will have to add logic because I'm pretty sure you don't want to always color/bold this specific words, but here you go with a quick example:
NSString *title = #"Nancy tagged Clothing: Season 2, Episode 5. where do they find all the old clothes";
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:title];
// Color text for range of string
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor grayColor]
range:[title rangeOfString:#"Nancy"]];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor grayColor]
range:[title rangeOfString:#"Clothing"]];
// Bold (be careful, I have used system font with bold and 14.0 size, change the values as for yourself)
[attributedString addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:14.0 weight:UIFontWeightBold]
range:[title rangeOfString:#"Season 2"]];
[attributedString addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:14.0 weight:UIFontWeightBold]
range:[title rangeOfString:#"Season 5"]];
self.tagCommentLabel.attributesText = attributedString;
Edit: To make it work with your code, delete the line:
self.tagCommentLabel.text = [NSString stringWithFormat:#"%# tagged %#: %# %#",tag.user.name , title, episode, tag.comment];
Instead of mine assigning to title with static text, change it to:
NSString *title = [NSString stringWithFormat:#"%# tagged %#: %# %#",tag.user.name , title, episode, tag.comment];

Formatting multi line text in UILabel?

I would like to have label that has 4 lines. If text is not long enough for 4 lines, nothing happens. But if text is 4 lines or longer I want it to have a little different color just for last line.
Is there easy way to do this. I know i can with attributed string change font of label, but how do i get text that is in forth line?
Use NSAttributedString to format paragraphs, lines, words or even single characters how ever you want. To get the text on the 4th line, separate your text on its \n characters.
If you don't have any \n, you can use getLineStart:end:contentsEnd:forRange:, adapted from here
NSString *string = /* assume this exists */;
unsigned length = [string length];
unsigned lineStart = 0, lineEnd = 0, contentsEnd = 0;
NSMutableArray *lines = [NSMutableArray array];
NSRange currentRange;
while (lineEnd < length) {
[string getLineStart:&lineStart end:&lineEnd
contentsEnd:&contentsEnd forRange:NSMakeRange(lineEnd, 0)];
currentRange = NSMakeRange(lineStart, contentsEnd - lineStart);
[lines addObject:[string substringWithRange:currentRange]];
}
EDIT
After rereading the question, this may not be exactly what you are after. Check out the full answer here:
In iOS 6+ you can render attributed strings using the attributedText property of UILabel.
Following a code example:
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:#"Hello. That is a test attributed string."];
[str addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:NSMakeRange(3,5)];
[str addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(10,7)];
[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"HelveticaNeue-Bold" size:20.0] range:NSMakeRange(20, 10)];
label.attributedText = str;
As you can see in the code you can select a different color text for the different range of characters. In your case you can put the different font color for the chars in the string for the last line.
In order to check the range of chars for the last line you can use:
NSUInteger characterCount = [myString length];
And then characterCount divided for number of chars you can put in each line depending on the width of it.

Two text colors in one UITableViewCell text label

I have a text label inside a UITableViewCell consisting of two words.
How can I change the color of the words; making the first word green, and the second word red?
NSString *twoWords = #"Green Red";
NSArray *components = [twoWords componentsSeparatedByString:#" "];
NSRange greenRange = [twoWords rangeOfString:[components objectAtIndex:0]];
NSRange redRange = [twoWords rangeOfString:[components objectAtIndex:1]];
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:twoWords];
[attrString beginEditing];
[attrString addAttribute: NSForegroundColorAttributeName
value:[UIColor greenColor]
range:greenRange];
[attrString addAttribute: NSForegroundColorAttributeName
value:[UIColor redColor]
range:greenRange];
[attrString endEditing];
Then you can use attrString directly on a UILabel (> iOS 6, check Apple Documentation).
The simplest way to do this would be with an nsattributedstring in iOS 6.0 or later. You would allocate one of those and in the titleLabel (or any other object that holds text) of the UITableViewCell. If you're using the titleLabel you would do this:
[cell.titleLabel setAttributedText:yourAttributedString];
To setup the colors with an NSAttributedString, do this:
NSMutableAttributedString* attributedString = [[NSMutableAttributedString alloc] initWithString:stringToManipulate];
[attributedString beginEditing];
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(0, widthOfFisrtWord)];
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(widthOfFisrtWord, widthOfSecondWord)];
[attributedString endEditing];
Note that the ranges provided above using NSMakeRange won't be the ranges you need. You'll have to change the range to fit your own needs depending if the two words have a space in between them or other characters.
Apple Documentation:
NSAttributedString
NSAttributedString UIKit Additions Reference
NSMutableAttributedString
This question addresses getting part of a string, which you would need to do. Instead of modifying the text with BOLD though, you can use this question to get an idea of how to change the color.
By using NSAttributedString string you can set two different colors.NSAttributedString
once check this one.

Resources