Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSAttributedString change color at end of string

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.

like image 562
Raconteur Avatar asked Oct 01 '13 18:10

Raconteur


2 Answers

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.

like image 153
Raconteur Avatar answered Nov 19 '22 17:11

Raconteur


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

like image 1
kkodev Avatar answered Nov 19 '22 17:11

kkodev