How to stop cursor changing position when I setAttributedText in UITextView delegate method textViewDidChange
Asked Answered
M

2

9

The following code changes "test" in the textView's string to red color but it also has the effect of moving the cursor to the end of the text block when textViewDidChange is called (Aka when any text editing is made which is very annoying).

How can I prevent the cursor moving when I setAttributedText in textViewDidChange?

- (void)textViewDidChange:(UITextView *)textView {

    NSString* currentString = self.textView.text;
    NSMutableAttributedString* string = [[NSMutableAttributedString alloc]initWithString:currentString];
    NSArray *words=[currentString componentsSeparatedByString:@" "];

    for (NSString *word in words) {
        if ([word isEqualToString:@"test"]) {
            // change color
            NSRange range=[currentString rangeOfString:word];
            [string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:range];
        }
    }

    // assign new color to textView's text
    [self.textView setAttributedText:string];
}
Macaronic answered 21/1, 2016 at 3:32 Comment(2)
FYI - your code will only ever find the first occurrence of "test".Austronesia
Yes that's another thing I want to fix :PMacaronic
A
16

Simply save and restore the selected range:

NSRange selectedRange = self.textView.selectedRange;
self.textView.attributedText = string;
self.textView.selectedRange = selectedRange;
Austronesia answered 21/1, 2016 at 3:35 Comment(1)
That doesn't work if you have string longer than textField can display and move cursor to the beginning. When you type text, cursor stays in one position.Corvine
C
0

Best way is to temporary disable delegate, I also tried with cursor save and restore but that made problems when there is custom changing on shouldChangeTextIn... on the end disabling delegate resolved all problems:

Objective C:

id<UITextViewDelegate> tempDelegate = textView.delegate;
// Do your text changes
textView.delegate = tempDelegate;

Swift:

let tempDelegate = self.textView.delegate
// Do your text changes
self.textView.delegate = tempDelegate
Chole answered 7/7, 2022 at 9:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.