String and attributions problems - ios

Ive been messing around with this without proper results. My code is as follows
NSMutableAttributedString *nameString = [[NSMutableAttributedString alloc]initWithString:((User *)appDelegate.users[self.currentUserIndex]).name];
[nameString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"Helvetica-Bold" size:12.0] range:NSMakeRange(0, nameString.length)];
NSString *adviceString = [[NSString alloc] initWithFormat:#"%#, remember be extra aware of the \n cat today. The dog index is 4, dogcatcher \n suggests you should at minimum wear \n a dog and apply cat...", [nameString string]];
So, it doesn't bold the username as desired. I tried using NSAttributedString for adviceString but then I can't use the initWithFormat: method and list the variables after the string, and I don't see any NSAttributedString equivalent. I wanted to you NSAttributedString instead of NSMutableAttributedString, but it doesn't seem to recognise the addAttribute:value:fontWithName:range method. Can anybody help me out? Any help much appreciated.

That's for sure, you need to use NSAttributedString also for adviceString to get attributed.
The code goes like this, if you need to use stringWithFormat:
NSString *fullName = #"Anoop Kumar Vaidya";
NSMutableAttributedString *attributedName = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:#"Hello %#", fullName]
attributes:#{NSFontAttributeName : [UIFont boldSystemFontOfSize:[UIFont systemFontSize]]}];
In the attributes you can add few more desired/required attributes.
EDIT 2:
You may like to use some methods as :
-(NSMutableAttributedString *)normalString:(NSString *)string{
return [[NSMutableAttributedString alloc] initWithString:string
attributes:#{}];
}
-(NSMutableAttributedString *)boldString:(NSString *)string{
return [[NSMutableAttributedString alloc] initWithString:string
attributes:#{NSFontAttributeName : [UIFont boldSystemFontOfSize:[UIFont systemFontSize]]
}];
}
And then use them as per your requirement:
NSMutableAttributedString *attributedName = [self boldString:fullName];
[attributedName appendAttributedString:[self normalString:#" is creating one"]];
[attributedName appendAttributedString:[self boldString:#" bold"]];
[attributedName appendAttributedString:[self normalString:#" string."]];

Related

Bolding an nsstring

I have looked online for ways to bold a NSString and either it's not there or I can't seem to find it. I simply want to bold the word in the NSString but so far, what I have done is not woking:
NSString *player1Name = [[UIFont boldSystemFontOfSize:12] fontName];
I have relied on this to make "player1Name" bold but it doesn't work at all.
When I run it I get this:
Thanks in advance to anyone who helps me figure out the solution.
You can not bold a NSString... Try a NSAttributedString...
NSAttributedString *player1Name = [[NSAttributedString alloc] initWithString:#"name" attributes:#{NSFontAttributeName : [UIFont boldSystemFontOfSize:12]}];
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSAttributedString_Class/
fontName is a property on UIFont
[[UIFont boldSystemFontOfSize:12] fontName]
returns the font name HelveticaNeueInterface-MediumP4
Try this:
NSString *myString = #"My string!";
NSAttributedString *myBoldString = [[NSAttributedString alloc] initWithString:myString
attributes:#{ NSFontAttributeName: [UIFont boldSystemFontOfSize:35.0] }];
Also you can set range for particular text like:
NSString *boldFontName = [[UIFont boldSystemFontOfSize:12] fontName];
NSString *yourString = ...;
NSRange boldedRange = NSMakeRange(2, 4);
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:yourString];
[attrString beginEditing];
[attrString addAttribute:kCTFontAttributeName
value:boldFontName
range:boldedRange];
[attrString endEditing];
You can't make NSString bold. Instead of that you can make UILabel text into bold. Because UILabels are for UI representation & NSStrings are just objects. So make your UILabel bold
[infoLabel setFont:[UIFont boldSystemFontOfSize:16]];

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

Why does this NSMutableAttributedString addAttribute work only if I use a mutableCopy

I have the following code :
NSMutableAttributedString *attrS = [[NSMutableAttributedString alloc] initWithString:#"• Get Tested Son"];
NSMutableAttributedString *boldS = [[NSMutableAttributedString alloc] initWithString:#"Son"];
[boldS addAttribute:NSFontAttributeName value:SOMEBOLDFONT range:NSMakeRange(0, boldS.length)];
[attrS replaceCharactersInRange:[attrS.string rangeOfString:boldS.string]
withAttributedString:boldS];
As you can see, I want to bold the Son part. This does not work if I do the above statements but only works if I do :
[[attrS mutableCopy] replaceCharactersInRange:[attrS.string rangeOfString:boldS.string]
withAttributedString:boldS];
What might be the reason for that?
addAttribute works regardless of whether you take a mutableCopy. Your question is based on a false assumption. It therefore has no answer.
Run this:
NSMutableAttributedString *attrS = [[NSMutableAttributedString alloc] initWithString:#"• Get Tested Son"];
NSMutableAttributedString *boldS = [[NSMutableAttributedString alloc] initWithString:#"Son"];
UIFont *someBoldFont = [UIFont fontWithName:#"Arial" size:23.0f];
[boldS addAttribute:NSFontAttributeName value:someBoldFont range:NSMakeRange(0, boldS.length)];
NSMutableAttributedString *attrSCopy = [attrS mutableCopy];
[attrS replaceCharactersInRange:[attrS.string rangeOfString:boldS.string]
withAttributedString:boldS];
[attrSCopy replaceCharactersInRange:[attrS.string rangeOfString:boldS.string]
withAttributedString:boldS];
NSLog(#"%#", [attrS isEqual:attrSCopy] ? #"equal" : #"different");
It will output equal. Comment out the replaceCharactersInRange: for either attrS or attrSCopy and it will output different.

Display edited NSString in order

I have been working on this for a few days with help from this great community.
I have a NSArray that I need to edit NSStrings within. I have managed to detect a marker in the string and make it bold. However now I am trying to display the strings in the order that they are within the NSArray whilst maintaining the Bold that was added to the specific strings.
I can display the individual Bold String 'string' but I need it to be in order that it is within the array. I know of stringByAppendingString but this would put it at the end.
Any directions would be brilliant.
for (NSString *testWord in legislationArray) {
if ([testWord rangeOfString:#"BOLDME"].location != NSNotFound) {
//Remove Marker
NSString *stripped = [testWord stringByReplacingOccurrencesOfString:#"BOLDME" withString:#""];
//Get string and add bold
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:stripped];
NSRange selectedRange = [stripped rangeOfString:(stripped)];
[string beginEditing];
[string addAttribute:NSFontAttributeName
value:[UIFont fontWithName:#"Helvetica-Bold" size:18.0]
range:selectedRange];
[string endEditing];
//Where to go now with string?
}
}
cell.dynamicLabel.text = [legislationArray componentsJoinedByString:#"\n"];
EDIT
Based on the answers below I got it working however the bold method invokes this error:
componentsJoinedByString return a NSString, when you want a NSAttributedString.
Plus, you're setting your text to a receiver that awaits a NSString (cell.dynamicLabel.text), where what you want should be cell.dynamicLabel.attributedText.
Since there is no equivalent to componentsJoinedByString for a NSAttributedString return, you have to do it the oldway, with a for loop, starting with initializing a NSMutableAttributedString, and adding to it each components (that you may "transform") to it.
Here is a example and related question.
Just use additional array. Change your code to
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] init];
for (NSString *testWord in legislationArray) {
if ([testWord rangeOfString:#"BOLDME"].location != NSNotFound) {
//Remove Marker
NSString *stripped = [testWord stringByReplacingOccurrencesOfString:#"BOLDME" withString:#""];
//Get string and add bold
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:stripped];
NSRange selectedRange = [stripped rangeOfString:(stripped)];
[string beginEditing];
[string addAttribute:NSFontAttributeName
value:[UIFont fontWithName:#"Helvetica-Bold" size:18.0]
range:selectedRange];
[string endEditing];
//Where to go now with string?
[attrString appendAttributedString:string];
}
else
{
[attrString appendAttributedString:[[NSAttributedString alloc] initWithString:testWord]];
}
// NEW LINE
[attrString appendAttributedString:[[NSAttributedString alloc] initWithString:#"\n"]];
}
cell.dynamicLabel.attributedText = attrString;
UPDATE:
Your additional issue is not a error - this is a way how XCode shows attributed strings in debug window:

How to show multiple line text that has different font without using multiple Labels

I have to show a text paragraph that contains few words in bold font. ex.
If I use different labels then on changing the orientation it does not resize properly.
Can anyone tell me what can the best way to do it.
You can use an UITextView using NSAttributedString (have a look to the apple doc)
And you have an explanation of how to use it here.
You can find the range of your word and change the font or the color or whatever using :
- (IBAction)colorWord:(id)sender {
NSMutableAttributedString *string = [[NSMutableAttributedString alloc]initWithString:self.text.text];
NSArray *words = [self.text.text componentsSeparatedByString:#" "];
for (NSString *word in words)
{
if ([word hasPrefix:#"#"])
{
NSRange range=[self.text.text rangeOfString:word];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:range];
}
}
[self.text setAttributedText:string];
}
You have to use a NSAttributedString and assign it to the UITextField, this is an example:
UIFont *boldFont = [UIFont boldSystemFontOfSize:fontSize];
UIFont *regularFont = [UIFont systemFontOfSize:fontSize];
NSMutableAttributedString *myAttributedString = [[NSMutableAttributedString alloc] initWithString:yourString];
[myAttributedString addAttribute:NSFontAttributeName
value:boldFont
range:NSMakeRange(0, 2)];
[myAttributedString addAttribute:NSFontAttributeName
value:regularFont
range:NSMakeRange(3, 5)];
[self.description setAttributedText:myAttributedString];
Find all the doc here:
NSAttributedString
For your case, you can use a webView and load it with your string:
[webView loadHTMLString:[NSString stringWithFormat:#"<html><body style=\"background-color: transparent;\">This is <b><i>Test</b></i> dummy text ..</body></html>"] baseURL:nil];

Resources