Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing attributes on a UITextView without resetting the attributedText property

I have a UITextView that is parsed and has its attributes changed when certain characters are typed. The text is not changed, only the attributes that describe the text's formatting.

If I parse on every character entry, I'm essentially grabbing the text, creating an attributed string with the right formatting, and setting the attributedText property of the textview to my new attributed string. This totally breaks autocorrect, the double-space shortcut, and spell check.

If I parse only when certain special characters are typed, this works a little better, but I get weird bugs like the second word of every sentence is capitalized.

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if (text.length == 0) {
        return YES;
    }
    unichar firstCharacterInText = [text characterAtIndex:0];
    if (/* special character */) {
        [self processTextView];
    }
}

- (void) processTextView {
    NSString *text = self.text;

    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];

    [attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:kFontRegular size:12.0f] range:NSMakeRange(0, text.length)];
    [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor textColor] range:NSMakeRange(0, text.length)];
    // set other properties 
}

My question is: Is there a way to change the text attributes of my text view without resetting the textview's attributedText property and breaking all those handy features of UITextView?

like image 918
Soroush Khanlou Avatar asked Apr 23 '13 02:04

Soroush Khanlou


1 Answers

To elaborate on fatuhoku's comment above. You can call

func setAttributes(_ attrs: [NSAttributedString.Key: Any]?, range: NSRange)

On the text view's .textStorage.

like image 100
Daniel Avatar answered Oct 24 '22 20:10

Daniel