Search code examples
iosswiftuitextviewnsattributedstring

Adding different color while editting text in UITextView irrespective of cursor position in Swift


I have a textview where I pre populate it with some required comments for eg: "Hi this is John" would show up in textview with blue color. Now what I need is, whatever new editing is done in textview it would come up in black. So, if I edit the text to "Hi this is Steve". Only "Steve" should be in black and rest should be in blue. I know I will have to use NSAttributedString, but how do I go about it?

Right now I do this on my view load

descriptionTextView.text = myString
descriptionTextView.textColor = UIColor.blue

And this on texteditting

func textViewDidBeginEditing(_ textView: UITextView) {
    descriptionTextView.textColor = UIColor.black
}

But this will change everything to black. Any ideas?


Solution

  • You can achieve this by using UITextViewDelegate

    Set delegate for UITextView and make a global variable of NSRange as:

    IBOutlet UITextView *textVw;
    NSRange textRange;
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    
        UIColor *color = [UIColor blueColor]; // set initial needed color
        NSString *string = @"Hi this is John"; // set initial string to color
        NSDictionary *attrs = @{ NSForegroundColorAttributeName : color };
        NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:string attributes:attrs];
        textVw.attributedText = attrStr;
    
        //Set delegate of UITextView
        [textVw setDelegate:self];
    }
    
    #pragma UITextViewDelegate Methods.
    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    {
         //Check string is written or backspace (with prediction on).
         if (text.length > 1) {
    
             //Make Range for black text in textview.
             textRange = NSMakeRange(range.location, text.length + 1);
    
             return YES;
         }
    
         //Check string is written or backspace.
         if (text.length > 0 && ![text isEqualToString:@" "]) {
    
             //Make Range for black text in textview.
             textRange = NSMakeRange(range.location, 1);
    
            return YES;
         }
    
        return YES;
    }
    
    -(void)textViewDidChange:(UITextView *)textView {
    
        //Check there are some value is written or not.
        if (textRange.length > 0) {
    
            //Check textview is rest with initial value or not.
            if ([textVw.text caseInsensitiveCompare:@"Hi this is John"] == NSOrderedSame) {
    
                //Rest value so make string as blue.
                UIColor *color = [UIColor blueColor]; // set initial needed color
                NSString *string = @"Hi this is John"; // set initial string to color
                NSDictionary *attrs = @{ NSForegroundColorAttributeName : color };
                NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:string attributes:attrs];
                textVw.attributedText = attrStr;
    
            } else {
    
                NSMutableAttributedString *text =
                [[NSMutableAttributedString alloc]
                 initWithAttributedString: textVw.attributedText];
    
                [text addAttribute:NSForegroundColorAttributeName
                             value:[UIColor blackColor]
                             range:textRange];
    
                //Add new Attributed value to textView with black color.
                [textVw setAttributedText: text];
    
            }
    
            //After assign value to textfiled make textRange varibale as default value for safe handler.
            textRange = NSMakeRange(0, 0);
        }
    }
    
    - (void)textViewDidChangeSelection:(UITextView *)textView
    {
          //Check there are some value is written or not.
    
          if (textRange.length > 1) {
                 //For maintain cursor position with prediction on.
                 [textView setSelectedRange:NSMakeRange(textRange.location + textRange.length , 0)];
    
          } else if (textRange.length > 0) {
                //For maintain cursor position.
                [textView setSelectedRange:NSMakeRange(textRange.location + 1, 0)];
          }
    }