I have a UITextView
and when the user is entering text into it, I want to format the text on the fly. Something like syntax highlighting...
For that I'd like to use UITextView
...
Everything works fine expect one problem: I take the text from the text view and make an NSAttributedString
from of it. I make some edits to this attributed string and set it back as the textView.attributedText
.
This happens everytime the user types. So I have to remember the selectedTextRange
before the edit to the attributedText
and set it back afterwards so that the user can continue typing at the place he was typing before. The only problem is that once the text is long enough to require scrolling, the UITextView
will now start scrolling to the top if I type slowly.
Here is some sample code:
- (void)formatTextInTextView:(UITextView *)textView
{
NSRange selectedRange = textView.selectedRange;
NSString *text = textView.text;
// This will give me an attributedString with the base text-style
NSMutableAttributedString *attributedString = [self attributedStringFromString:text];
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"#(\\w+)" options:0 error:&error];
NSArray *matches = [regex matchesInString:text
options:0
range:NSMakeRange(0, text.length)];
for (NSTextCheckingResult *match in matches)
{
NSRange matchRange = [match rangeAtIndex:0];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:matchRange];
}
textView.attributedText = attributedString;
textView.selectedRange = selectedRange;
}
Is there any solution without using CoreText directly? I like the UITextView
s ability to select text and so on....
I am not sure that this is correct solution, but it works.
Just disable scrolling before formatting text and enable it after formatting
- (void)formatTextInTextView:(UITextView *)textView
{
textView.scrollEnabled = NO;
NSRange selectedRange = textView.selectedRange;
NSString *text = textView.text;
// This will give me an attributedString with the base text-style
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"#(\\w+)" options:0 error:&error];
NSArray *matches = [regex matchesInString:text
options:0
range:NSMakeRange(0, text.length)];
for (NSTextCheckingResult *match in matches)
{
NSRange matchRange = [match rangeAtIndex:0];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:matchRange];
}
textView.attributedText = attributedString;
textView.selectedRange = selectedRange;
textView.scrollEnabled = YES;
}