changing colour of a part of string objective c [duplicate] - objective-c

This question already has answers here:
Are there any analogues of [NSString stringWithFormat:] for NSAttributedString
(4 answers)
Closed 6 years ago.
I have a string like this
NSString * string = [[NSString alloc]initwithformat: #"The current balance left is %# out of %#",leftAmount,totalAmount];
How can i change the colour of string recieved as %# without knowing the range of the recieved string.

Do something like this,
NSString *leftAmount = #"1000";
NSString *totalAmount = #"2000";
UIColor *color = [UIColor redColor];
NSDictionary *attrs = #{ NSForegroundColorAttributeName : color };
NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:leftAmount attributes:attrs];
NSAttributedString *attrStr1 = [[NSAttributedString alloc] initWithString:totalAmount attributes:attrs];
NSMutableAttributedString * string = [[NSMutableAttributedString alloc] initWithString:#"The current balance left is "];
[string appendAttributedString:attrStr];
NSMutableAttributedString * string1 = [[NSMutableAttributedString alloc] initWithString:#" out of "];
[string1 appendAttributedString:attrStr1];
[string appendAttributedString:string1];
NSLog(#"Your Full String - %#", string);
Hope this will help you.

do something like this,
NSString *leftAmount,*totalAmount;
leftAmount = #"1000";
totalAmount = #"2000";
NSString * string = [NSString stringWithFormat:#"The current balance left is %# out of %#",leftAmount,totalAmount];
NSDictionary *attribs = #{
NSForegroundColorAttributeName: [UIColor blueColor],
NSFontAttributeName: [UIFont systemFontOfSize:12]
};
NSMutableAttributedString *attributedText =
[[NSMutableAttributedString alloc] initWithString:string
attributes:attribs];
UIColor *grayColor = [UIColor colorWithRed:186.0f/255.0f green:186.0f/255.0f blue:186.0f/255.0f alpha:1];
NSRange leftAmountTextRange = [string rangeOfString:leftAmount];
[attributedText setAttributes:#{NSForegroundColorAttributeName:grayColor}
range:leftAmountTextRange];
It'll also calculate the dynamic data value range.
I hope it will helps you,
Thanks.

Related

NSMutableAttributedString with NSRange issue

I have the following string
22\nShaʻban\n1435
and i'm using NSMutableAttributedString to format the above string using multiple fonts as follows:
NSString* orgString=#"22\nShaʻban\n1435";
NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:[dateStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
UIFont *dayFont=[UIFont fontWithName:#"Helvetica-Bold" size:40.0f];
UIFont *monthFont=[UIFont fontWithName:#"Arial" size:22.0f];
UIFont *yearFont=[UIFont fontWithName:#"Arial" size:20.0f];
//format day part
[attString addAttribute:NSFontAttributeName value:dayFont range:NSMakeRange(0,2)];
//format month part
[attString addAttribute:NSFontAttributeName value:monthFont range:NSMakeRange(3,[self indexOf:[dateStr substringFromIndex:3] andSearchChar:#"\n"])];
//format year part, app crashes here
[attString addAttribute:NSFontAttributeName value:yearFont range:NSMakeRange([self indexOf:[dateStr substringFromIndex:3] andSearchChar:#"\n"]+1,[dateStr length])];
- (int) indexOf:(NSString*)orgStr andSearchChar:(NSString *)charToSearc {
NSRange range = [orgStr rangeOfString:charToSearc];
if ( range.length > 0 ) {
return range.location;
} else {
return -1;
}
}
i don't know why it crashes when trying to format the last part, i made arrange from the last position in part two +1 to the length of the string, any help please
NSRange NSMakeRange (
NSUInteger loc,
NSUInteger len
);
A range is a location and a length, not a start and end location. So you need to change how you calculate the range content.
Or, split the source string apart, create an attributed string for each part and then append them together.
I'd suggest this:
NSString* orgString=#"22\nShaʻban\n1435";
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] init];
UIFont *dayFont = [UIFont fontWithName:#"Helvetica-Bold" size:40.0f];
UIFont *monthFont = [UIFont fontWithName:#"Arial" size:22.0f];
UIFont *yearFont = [UIFont fontWithName:#"Arial" size:20.0f];
NSArray *array = [orgString componentsSeparatedByString:#"\n"];
[attrString appendAttributedString:[[NSAttributedString alloc] initWithString:[array objectAtIndex:0] attributes:#{NSFontAttributeName: dayFont}]];
[attrString appendAttributedString:[[NSAttributedString alloc] initWithString:#"\n"]];
[attrString appendAttributedString:[[NSAttributedString alloc] initWithString:[array objectAtIndex:1] attributes:#{NSFontAttributeName: monthFont}]];
[attrString appendAttributedString:[[NSAttributedString alloc] initWithString:#"\n"]];
[attrString appendAttributedString:[[NSAttributedString alloc] initWithString:[array objectAtIndex:2] attributes:#{NSFontAttributeName: yearFont}]];
So, no NSRange issue. Plus as said by #Wain, you misunderstood what's a NSRange.
Instead of what you're doing, once you found the location, you had to put, as second parameter of NSMakeRange: nextLocation-currentLocation. Id est, for last one, something like this:
NSMakeRange([self indexOf:[dateStr substringFromIndex:3] andSearchChar:#"\n"]+1,
[dateStr length]-[self indexOf:[dateStr substringFromIndex:3] andSearchChar:#"\n"]+1)

How to combine 2 strings into one nsatributed string?

NSString * strTimeBefore = [timeBefore componentsJoinedByString:#" "];
NSString * strTimeAfter = [timeAfter componentsJoinedByString:#" "];
I want the resulting string to be an NSAttributedString where the time in strTimeAfter is in bold
You probably want something like:
NSString *boldFontName = [[UIFont boldSystemFontOfSize:12] fontName];
NSString *yourString = [NSString stringWithFormat:#"%# %#", strTimeBefore, strTimeAfter;
// start at the end of strTimeBefore and go the length of strTimeAfter
NSRange boldedRange = NSMakeRange([strTimeBefore length] + 1, [strTimeAfter length]);
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:yourString];
[attrString beginEditing];
[attrString addAttribute:NSFontAttributeName
value:boldFontName
range:boldedRange];
[attrString endEditing];
And my answer is cribbed from Jacob's answer to this very closely related question.
Take two attribute string in that store your first string into one attribute string without changing its attributes, In second attribute string store your second string with changing its attibutes and then append both attribute string into one NSMutableAttributeString Try like this below:-
NSString * strTimeBefore = [timeBefore componentsJoinedByString:#" "];
NSString * strTimeAfter = [timeAfter componentsJoinedByString:#" "];
NSAttributedString *attrBeforeStr=[[NSAttributedString alloc]initWithString:strTimeBefore];
NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:[NSColor yellowColor] forKey:NSBackgroundColorAttributeName];
NSFont *font = [[NSFontManager sharedFontManager] fontWithFamily:#"Arial" traits:NSBoldFontMask weight:5 size:14];
[attributes setObject:font forKey:NSFontAttributeName];
NSAttributedString *attrAftStr=[[NSAttributedString alloc]initWithString:strTimeAfter attributes:];
NSMutableAttributedString *string=[[NSMutableAttributedString alloc] init];
[string appendAttributedString:attrBeforeStr];
[string appendAttributedString:strTimeAfter];
Note: You can change font color as well in attribute string, if it is required.

NSAttributedString with dynamic ranges

I have to format a string with 3 styles. The string is something like:
1.0000 of 2.000
1.0000 has a foreground red color, of has a smaller font and 2.000 has to be green.
The problem is that the numbers could be in any range, so the first and the second numbers could be composed by 4,5,6 whatever chars.
How can I perform formatting of a string like that?
Edit-----------------
I add some more info: the string maintains its format. So for example this could be its template: N of N
Lets suppose you have these three :
NSString *string0 = #"1.0000"; NSString *string1 = #"of"; NSString
*string2 = #"2.000";
NSString *text = [NSString stringWithFormat:#"%# %# %#",
string0 ,string1,string2];
//whole String attribute
NSDictionary *attribs = #{
NSForegroundColorAttributeName:[UIColor whiteColor],
NSFontAttributeName:[UIFont systemFontOfSize:10]
};
NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:text attributes:attribs];
NSRange string0Range = [text rangeOfString:string0];
NSRange string1Range = [text rangeOfString:string1];
NSRange string2Range = [text rangeOfString:string2];
[attributedText setAttributes:#{NSForegroundColorAttributeName:[UIColor redColor], NSFontAttributeName:[UIFont systemFontOfSize:15] range:string0Range];
[attributedText setAttributes:#{NSForegroundColorAttributeName:[UIColor blackColor], NSFontAttributeName:[UIFont systemFontOfSize:12] range:string1Range]; [attributedText setAttributes:#{NSForegroundColorAttributeName:[UIColor greenColor], NSFontAttributeName:[UIFont systemFontOfSize:15] range:string2Range];
[yourLabel setAttributedText:attributedText];
Use NSScanner or NSRegularExpression to find the numeric expression and its pieces.
The simplest solution would be :
NSString* myString = #"12.345 of 56.789";
NSMutableAttributedString * tempString = [[NSMutableAttributedString alloc] initWithString:myString];
NSRange midrange = [tempString.string rangeOfString:#"of"];
[tempString addAttributes:#{NSFontAttributeName : [UIFont fontWithName:#"HelveticaNeue" size:16.6],
NSForegroundColorAttributeName : [UIColor redColor]}
range:NSMakeRange(0, midrange.location)];
[tempString addAttributes:#{NSFontAttributeName : [UIFont fontWithName:#"HelveticaNeue" size:16.6],
NSForegroundColorAttributeName : [UIColor blackColor]}
range:midrange];
[tempString addAttributes:#{NSFontAttributeName : [UIFont fontWithName:#"HelveticaNeue" size:16.6],
NSForegroundColorAttributeName : [UIColor greenColor]}
range:NSMakeRange(midrange.location + midrange.length, tempString.length - midrange.location - midrange.length)];
yourElement.attributedText = tempString;

Convert NSString to HTML and set HTML text into UILabel [duplicate]

This question already has answers here:
How to create a UILabel or UITextView with bold and normal text in it?
(5 answers)
Closed 9 years ago.
Is it possible to convert a NSString to html and set as a label?
The code below shows the NSString I want to set finalPrice as bold text and finalStr&shipping string as normal text
NSString *myText = [NSString
stringWithFormat:
#"%#\nFinal price including $%.2f Shipping and all discount: <b>$%.2f</b>",
finalStr,shipping,finalPrice];
lbl.text = myText;
I want to set multiple color and multiple text type into same dyanamic label.
use following label for bold effects. Or you can get code from that class.
DAAttributedStringUtils
and also see this
Different Label
Edit
NSString *myText = [NSString stringWithFormat:#"%#\nFinal price including $%.2f Shipping and all discount: %%B$%.2f%%b",finalStr,shipping,finalPrice];
DAAttributedLabel* lbl = [[DAAttributedLabel alloc] initWithFrame:CGRectMake(30.0f, 30.0f, 260.0f, 24.0f)];
lbl.backgroundColor = [UIColor colorWithRed:0.9f green:0.9f blue:1.0f alpha:1.0f];
lbl.text = (id)[formatter formatString:myText];
[self.view addSubview:lbl];
Try using NSAttributedString
There are already several questions around this here like
How do you use NSAttributedString?
NSString * textString = #"Hello Bold";
NSInteger _stringLength = [textString length];
NSMutableAttributedString * attString = [[NSMutableAttributedString alloc] initWithString:textString];
[attString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"Helvetica" size:14.0f]; range:NSMakeRange(0, _stringLength)];
[attString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"Helvetica-Bold" size:14.0f]; range:NSMakeRange(6, 4)];
myLabel.attributedText = attString;
(code not tested)
Edit:
label.attributedText is only available for iOS 6.0+
FYI, the answer above suggesting the use of DAAttributedStringUtils and DAAttributedLabel didn't mention that these are convenience classes for the use of NSAttributedString. They make formatting NSAttributedString instances a little easier. As an example, here's how to do the same formatting described about by HAS using DAAttributedStringUtils:
float finalPrice = 34.99, shipping = 4.99;
// Setup the formatter
DAAttributedStringFormatter* formatter = [[DAAttributedStringFormatter alloc] init];
formatter.defaultFontFamily = #"Georgia";
formatter.defaultFontSize = 12.0f;
formatter.colors = #[ [UIColor blackColor], [UIColor redColor] ];
NSAttributedString* attrStr = [formatter formatString:#"%0C%0FRed Courier Text %1C%1FBlue Arial Text %0CRed Arial Text"];
// setup base strings
NSString *finalStr = #"Some Text. ";
NSString *shippingAttributed = [NSString stringWithFormat:#"%%B%%1C$%.2f%%b%%c", shipping];
NSString *middleText0 = #"Final price including ";
NSString *middleText1 = #" Shipping and all discount: ";
NSString *finalPriceAttributed = [NSString stringWithFormat:#"%%B%%1C$%.2f%%b%%c", finalPrice];
// Format the strings
self.label.attributedText = [formatter formatString:[NSString stringWithFormat:#"%#%#%%B%%1C%#%%b%%c%#%%B%%1C%#", finalStr, shippingAttributed, middleText0, middleText1, finalPriceAttributed];
Somewhat less code, and I think easier to understand. FYI, the formatter string in the last line contains codes that are used to modify the format of portions of the string. Those codes use double percents (

How to create an NSarray with NSAttributedStrings but keeping the attributes within the array?

I want to store different strings with different attributes and store all of them in one array and then display the objects in one label but each object with its respective attribute.
Any suggestions?
EDIT: Solution derived from rmaddy's answer
NSDictionary *redAttrs = #{NSForegroundColorAttributeName:[UIColor redColor]};
NSDictionary *greenAttrs = #{NSForegroundColorAttributeName:[UIColor colorWithRed:0.118 green:0.506 blue:0.000 alpha:1.000]};
NSDictionary *orangeAttrs = #{NSForegroundColorAttributeName:[UIColor orangeColor]};
NSString *stringUm = #"Brazil";
NSString *stringDois = #"USA";
NSString *stringTres = #"England";
NSMutableAttributedString *redString = [[NSMutableAttributedString alloc] initWithString:stringUm];
[redString setAttributes:redAttrs range:NSMakeRange(0,4)];
NSMutableAttributedString *greenString = [[NSMutableAttributedString alloc] initWithString:stringDois];
[greenString setAttributes:greenAttrs range:NSMakeRange(0,2)];
NSMutableAttributedString *orangeString = [[NSMutableAttributedString alloc] initWithString:stringTres];
[orangeString setAttributes:orangeAttrs range:NSMakeRange(0,4)];
NSArray *myStrings = [[NSArray alloc] initWithObjects:redString, greenString, orangeString, nil];
NSLog(#"%#", [myStrings description]);
NSMutableAttributedString *result = [[NSMutableAttributedString alloc]init];
NSAttributedString *delimiter = [[NSAttributedString alloc] initWithString: #", "];
for (NSAttributedString *str in myStrings) {
if (result.length) {
[result appendAttributedString:delimiter];
}
[result appendAttributedString:str];
}
_lblUm.attributedText = result;
Your question is very unclear. But based on your comment to gerrytan's answer, your goal is clearer.
If you have an array of NSAttributedString objects, then you can create a single string by appending them all together with an NSMutableAttributedString.
NSArray *myStrings = ... // your array of NSAttributedString objects
NSMutableAttributedString *result = [[NSMutableAttributedString alloc] init];
// Put this delimiter between each string - change as desired
NSAttributedString *delimiter = [[NSAttributedString alloc] initWithString:#", "];
for (NSAttributeString *str in myStrings) {
if (result.length) {
[result appendAttributedString:delimiter];
}
[result appendAttributedString:str];
}
myLabel.attributedText = result;
UILabel only supports one NSAttributedString. I think what you can do is to place multiple UILabel side by side for each string on the array