UITextView or UITextField of XZ_iOS modifies the color of some text entered in real time (below)

When the project was developed, such a function was used, which is similar to the topic of Weibo. When the user clicks, the keyword text needs to be inserted into the textView, and it will be displayed in red. When the user enters it, it will be a black font;
That is, the font between two [] is red.
The final effect:


First of all, to achieve this effect, the first thing that comes to mind is to use rich text NSMutableAttributedString to change the text in the [] range to red;
1> Use regular expressions to match the range of all the text in the [] range, and change all the text in the [] range to red;
2> Assign the modified text to textView, and modify the cursor position of textView;
// find all the keywords and modify the color
- (void)findAllKeywordsChangeColor:(UITextView *)textView {
    NSString *string = textView.text;
    // record the cursor position
    NSRange rangeDefault = textView.selectedRange;
    
    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString: string];
    
    [attrStr addAttribute:NSForegroundColorAttributeName value:COLOR102 range: NSMakeRange(0, string.length)];
    
    NSString *pattern = @"\\[(.*?)\\]";
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options: NSRegularExpressionCaseInsensitive error:nil];
    
    // 匹配所有项
    NSArray *matches = [regex matchesInString:string options:0 range:NSMakeRange(0, string.length)];
    
    NSLog(@"matches ==== %@",matches);
    
    //
    for (int i = 0; i < matches.count; i++) {
        NSTextCheckingResult *result = matches[i];
        NSRange range = [result rangeAtIndex:0];
        NSLog(@"查找合适的位置location:%lu-----%lu",range.location,range.length);
        NSString *subStr = [attrStr.string substringWithRange:range];
        NSUInteger length = subStr.length;
        [attrStr addAttribute:NSForegroundColorAttributeName value:kXZMainBgColor range:NSMakeRange(range.location, length)];
    }
    [attrStr addAttribute:NSFontAttributeName value:self.textEdit.font range:NSMakeRange(0, string.length)];
    self.textEdit.attributedText = attrStr;
    // 恢复光标位置
    NSRange rangeNow = NSMakeRange(rangeDefault.location, 0);
    textView.selectedRange = rangeNow;
}
需要注意的是:在textView中,当输入文字的时候,下一个文字的颜色和字体等属性,是跟随前一个文字的颜色和字体属性进行设置的,所以,在修改完颜色之后,要统一设置一遍textView的文字的字体大小:
[attrStr addAttribute:NSFontAttributeName value:self.textEdit.font range:NSMakeRange(0, string.length)];
实现是可以了,但是,现在是在哪个方法实现这种效果呢,当输入文字的文字改变的时候进行修改,所以就在textViewDidChange代理方法中实现效果。
当我运行查看效果的时候,发现是如下的效果:
在键盘上拼拼音的时候,还没有拼好,拼音就已经进入了输入框,原因是:当我们在拼拼音的时候,textViewDidChange代理方法也是在执行的,只要执行就会把值赋给textView,所以就显示出来了。

解决这个问题的思路是:找到一个点,刚好我拼完拼音,写入的时候,再进行修改和赋值。查找资料发现textView还有联想词这一说法,就是在中文输入的时候,当拼拼音的时候,把一些可能的结果高亮展示出来,所以,我们就在改变颜色赋值之前需要做个判断,判断当前是否联想词的高亮状态,将代码修改为如下:
- (void)textViewDidChange:(UITextView *)textView {

    UITextRange *selectedRange = [textView markedTextRange];
    
    // 获取高亮字符的位置
    UITextPosition *position = [textView positionFromPosition:selectedRange.start offset:0];
    // 如果没有高亮字符,修改颜色赋值
    if (!position) {
        [self findAllKeywordsChangeColor:textView];
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325918180&siteId=291194637