NSMutableAttributedString Crashing App - ios

I'm doing something wrong with the range (I think) in setting this NSMutableAttributedString. Can anyone tell me why this is crashing my program? It looks right to me, but I'm obviously wrong! Thanks.
NSString *placeHolderString = #"USERNAME";
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init];
float spacing = 5.0f;
// crashes on this line
[attributedString addAttribute:NSKernAttributeName
value:#(spacing)
range:NSMakeRange(0, [placeHolderString length])];
self.userNameTextField.attributedPlaceholder = attributedString;

What I think was causing your issue is that you were never really accounting for your placeholderString in the first place. In addition, your value parameter could simply use numberWithFloat as the application would then known what type you are using all the time.
Once you account for the placeHolderString, you are then going to use the length for the attributeString, as it now just contains the contents of your placeholderString. Then we just simply copy that string which contains your attribute using the UITextField property attributedText.
NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:placeHolderString];
float spacing = 5.0f;
[attributeString addAttribute:NSKernAttributeName
value:[NSNumber numberWithFloat:spacing]
range:(NSRange){0,[attributeString length]}];
userNameTextField.attributedText = [attributeString copy];
For more context, attributes like NSUnderlineStyleAttributeName exist and you can do some really powerful things with NSMutableAttributedString. Refer to the documentation for options.

Related

How to change properties of particular text in a label

I have a label and i set the text of the label programmatically. I want to set one of the word to be bold and the rest normal. However, i am unable to control the properties of the text. For example, I want this "This is an example" but am only able to achieve this "This is an example".
Try this:
NSString *text = #"This is an example";
NSString *textBold = #"example";
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];
[attributedString beginEditing];
[attributedString addAttribute:NSFontAttributeName
value:[UIFont boldSystemFontOfSize:20.0f]
range:[text rangeOfString:textBold]];
[attributedString endEditing];
[labelObj setAttributedText:attributedString];
Take a look at the attributedText property of the label. It lets you assign styled text using an NSAttributedString. Explaining how to build an NSAttributedString is beyond the scope of an SO answer, but you should be able to find ample information both in the Xcode help system and online.
Let me show you a demo about the attributedText.
NSDictionary*subStrAttribute1 = #{
NSForegroundColorAttributeName: [UIColor redColor],
NSStrikethroughStyleAttributeName:#2
};
NSDictionary *subStrAttribute2 =#{
NSForegroundColorAttributeName: [UIColor greenColor]
};
NSString *strDisplayText3 =#"Red and Green";
NSMutableAttributedString *attributedText3 = [[NSMutableAttributedString alloc] initWithString:strDisplayText3];
[attributedText3 setAttributes:subStrAttribute1 range:NSMakeRange(0,3)];
[attributedText3 setAttributes:subStrAttribute2 range:NSMakeRange(8,5)];
self.lblInfo3.attributedText= attributedText3;
Since ios6 uilabel supports attributed strings, So you can use it.
For your particular case below code will work-
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:#"This is an example"];
[string addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"HelveticaNeue-Bold" size:20.0] range:NSMakeRange(11, 7)];
label.attributedText = string;

String and attributions problems

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

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.

Setting custom font in UITextView with attributed string

I have a UITextView which contains an attributed string configured through storyboard. Now i want a custom font to be applied. I am doing it through code
textView.font = [UIFont fontWithName:kCustomFont size:textView.font.pointSize];
The problem is fonts get changed losing all the attributes. How do i fix it?
(Working on iOS 5 and above)
What's in your kCustomFont? If the FontName is wrong, even a single Character, the standard SystemFont will be used.
You should change it via NSMutableAttributedString's attributes.
I.e. use something like:
NSMutableAttributedString *mutableString = [[NSMutableAttributedString alloc] initWithAttributedString:textView.text];
NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil];
[mutableSrting addAttributes:attrs range:NSMakeRange(0, [mutableString length])];
textView.attributedText = mutableString;
[mutableString release];

Right to left UILabels

I need to display a text using a UILabel ( can't use UIWebView ), and it sometimes contains both Hebrew and English. using UILabel's default settings the sentence gets mixed up and doesn't make sense. I have failed to found a way to make UILabel display text rtl.
Does anybody know anyway to do that, or a code that implements this?
Have a look at this SO, it contains some info on this subject that might help you out.
It seems to work for some by adding the code \u200F to the strings to be displayed.
NSString *RTFstr = "1. בבוקר"; //This could be any right-to-left string
NSString *directionalString = [#"\u200F" stringByAppendingString:[note text]];
[someUITextView setString:directionalString];
This will work
-(void)fnForWritingDirection:(UILabel*)label textFor:(NSString *)stringForText{
NSMutableAttributedString* attrStr = [[NSMutableAttributedString alloc] initWithString: [stringForText stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setBaseWritingDirection:NSWritingDirectionRightToLeft];
[attrStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [attrStr length])];
label.attributedText=attrStr;
}

Resources