NSAttributedString change color at end of string - ios

This must be an easy thing to do, but I cannot figure it out.
I have a NSMutableAttributedString that has, for example, "This is a test" in it. I want to color the word "test" blue, which I do with this:
NSMutableAttributedString *coloredText = [[NSMutableAttributedString alloc] initWithString:#"This is a test"];
[coloredText addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(10,4)];
That works just fine. But now I want to set the text color back to black for anything typed after "test".
If I do:
[coloredText addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(coloredText.string.length, 1)];
I get an objectAtIndex:effectiveRange: out of bounds error. Assumedly because the range extends beyond the length of the string.
If I do:
[coloredText addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(coloredText.string.length, 0)];
The error goes away but typing after the word "test" remains blue.
How do I set the current color at the insertion point when it is at the end of the string??
Cheers for any input.

In case someone else stumbles upon this, I wanted to post the code I used to solve the problem. I ended up using Kamil's suggestion and adding:
NSAttributedString *selectedString = [textView.attributedText attributedSubstringFromRange:NSMakeRange(textView.attributedText.string.length - 1, 1)];
__block BOOL isBlue = NO;
[selectedString enumerateAttributesInRange:NSMakeRange(0, [selectedString length]) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(NSDictionary *attributes, NSRange range, BOOL *stop) {
isBlue = [[attributes objectForKey:NSForegroundColorAttributeName] isEqual:[UIColor blueColor]];
}];
if (isBlue) {
NSMutableAttributedString *coloredText = [[NSMutableAttributedString alloc] initWithAttributedString:textView.attributedText];
[coloredText addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(textView.attributedText.string.length - 1, 1)];
textView.attributedText = coloredText;
}
to the text changed handler.

You need to recalculate the attributes if the text changes, because their effective range doesn't automatically change with the length of text.

Related

iOS: Can I change color part of a Button Tittle?

I am new in iOS. I want to know how can I change the color for each part of UIButton title.
For example, a part of title in my UIButton is black and another the part of title in my UIButton is yellow
This is the describe image
Any help would be appreciated
U can use NSMutableAttributedString then add it to button with [button setAttributedTitle:attString forState:UIControlStateNormal];
To change color of a range in the Attribute String, read this, basically its just 1 of the attribute dictionary
Read this SO Question
I solve my question by using the code below.
For UILabel
NSMutableAttributedString *text =
[[NSMutableAttributedString alloc]
initWithAttributedString: self.lblFriendBand.attributedText];
[text addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:NSMakeRange(1, 2)];
[self.lblFriendBand setAttributedText: text];
For UIButton
NSMutableAttributedString *text2 =
[[NSMutableAttributedString alloc]
initWithAttributedString: self.btnFriendName.titleLabel.attributedText];
[text2 addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:NSMakeRange(1, 2)];
[self.btnFriendName setAttributedTitle:text2 forState:UIControlStateNormal];

Break UILabel into 2 lines with separate background?

http://imgur.com/yVkhHon.jpg
I want my text on lines but with separate background. How can i achieve this using UILabel ?
I tried padding etc but nothing works it just show single red box if i select background color for label.
Any help on how to get same effect like image ?
Use the following code:
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:self.yourLabel.text];
//EDITED
[text addAttribute:NSBackgroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, text.length/2)];
[text addAttribute:NSBackgroundColorAttributeName value:[UIColor orangeColor] range:NSMakeRange(text.length/2, text.length/2)];
[self.yourLabel setAttributedText: text];
Use NSAttributesString. Create a UILabel, create an NSAttributesString. Then instead of using setText of label, call setAttributedText using the string object you created earlier.
More help on Apple Documentation
[mutableAttributedString addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:selectedRange];

Segmented Control set attributed title in each segment

Actually i have a segmented control with 4 segment. I need to add attributed text in each segment like "Notification (2)". Here (2) will be in different color and Notification will be in different color.
I have search some third party library , But it doesn't work for me
Thanks & Regards
There is limitation to use attributed text as we use for label or button. But you may try below method to achieve your requirements.
-(void)SetSegmentValue:(NSString *)value forSegment:(int)index RangeOfBlueColor:(NSRange)bluecolorRange{
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:value];
NSMutableParagraphStyle *paragrahStyle = [[NSMutableParagraphStyle defaultParagraphStyle]mutableCopy];
[paragrahStyle setAlignment:NSTextAlignmentCenter];
[paragrahStyle setLineBreakMode:NSLineBreakByWordWrapping];
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragrahStyle range:NSMakeRange(0, value.length)];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor blackColor]
range:NSMakeRange(0, value.length)];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor blueColor]
range:bluecolorRange];
[attributedString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:13.0] range:NSMakeRange(0, value.length)];
int i =0 ;
for (UIView *v in [[[segment subviews] objectAtIndex:0] subviews]) {
if ([v isKindOfClass:[UILabel class]]&& i== index) {
UILabel *label=(UILabel *)v ;
[label setAttributedText:attributedString];
i++;
}
}
}
NOTE : You have to modified some part of code as it's just suggestion to solve your problem

NSAttributedString Strikethrough makes my attributed text disappear

I am trying to make an attributed string with a strikethrough. I can set other attributes such as foreground color and font size but when I try to set a strikethrough through part of the text, that part of the text disappears. Any Idea what might be causing it?
Below is the code. Thanks for looking!
// ...
//Price
NSLog(#"RESULT NUMBER %d", cell.result.resultId);
priceString = (priceString == nil) ? #"$150.00\n$100.00" : priceString;
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:priceString];
NSRange linebreak = [priceString rangeOfString:#"\n"];
if (linebreak.location != NSNotFound) {
[attributedString beginEditing];
// RegPrice
NSRange firstLine = NSMakeRange(0, linebreak.location);
// [attributedString addAttribute:NSFontAttributeName
// value:[UIFont boldSystemFontOfSize:11]
// range:firstLine];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor colorWithRed:0.7 green:0.7 blue:0.7 alpha:1]
range:firstLine];
#try {
[attributedString addAttribute:NSStrikethroughStyleAttributeName
value:#(NSUnderlineStyleSingle)
range:firstLine];
} #catch (NSException *e) {
NSLog(#"ATTRIBUTE EXCEPTION: %#", e);
}
// Sale Price
[attributedString addAttribute:NSFontAttributeName
value:[UIFont boldSystemFontOfSize:14]
range:NSMakeRange(linebreak.location + 1, priceString.length - (linebreak.location + 1))];
[attributedString endEditing];
}
cell.lblPrice.attributedText = attributedString;
return cell;
}
I had the same problem of string disappearing until I realised that the value for NSStrikethroughStyleAttributeName should be an NSNumber.
Therefore the code above should look like:
Objective-c
[attributedString addAttribute:NSStrikethroughStyleAttributeName
value: [NSNumber numberWithInt: NSUnderlineStyleSingle]
range:firstLine];
In Swift 4 attributes are passed using dictionary of type [NSAttributedStringKey: Any] and the strike trough style attribute would look like this:
[NSAttributedStringKey.strikethroughStyle: NSNumber(value: NSUnderlineStyle.styleSingle.rawValue)]
For me boldSystemFontOfSize: returns a font object with the HelveticaNeueInterface-MediumP4 font. Are you sure this font has a strike-through? Not all fonts do. Maybe try using a different font, one that you know has a strike-through.
I had the problem with the strikethrough text disappearing in a UILabel in iOS 7.0 only. It works fine in iOS 6.1 and 7.1.
There seems to be a bug in iOS 7.0 that strikethrough text disappears if the label is too high for the text by a certain amount. It works when I set the label's frame to a small enough height or call sizeToFit after setting the attributedText.

Can i set both current time and buffer limit on the same indicator

I need to show both current time (blue color) and buffer limit (gray color) on the same UIProgressView for my AVPlayer instance. Is it possible?
You need to use NSAttributedStrings to accomplish this.
Attributed Strings
Here is an example...
Make a custom UIView that contains a UILabel and UIProgressView as subviews.
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;
And here is an example of a custom UIProgressView implementation

Resources