ios - 用属性字符串替换 UITextViews 文本

标签 ios uitextview core-text nsattributedstring

我有一个 UITextView,当用户向其中输入文本时,我想即时设置文本的格式。类似于语法高亮...

为此我想使用 UITextView...

一切正常,但有一个问题:我从 TextView 中获取文本并从中生成一个 NSAttributedString。我对该属性字符串进行了一些编辑,并将其设置回 textView.attributedText

每次用户输入时都会发生这种情况。所以我必须在编辑 attributedText 之前记住 selectedTextRange 并在之后将其设置回去,以便用户可以在他之前输入的地方继续输入。唯一的问题是,一旦文本长到需要滚动时,如果我输入缓慢,UITextView 现在将开始滚动到顶部。

下面是一些示例代码:

- (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;
}

有没有不直接使用CoreText的解决方案?我喜欢 UITextView 能够选择文本等等....

最佳答案

我不确定这是不是正确的解决方案,但它确实有效。
只需在格式化文本前禁用滚动并在格式化后启用滚动

- (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;
}

关于ios - 用属性字符串替换 UITextViews 文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16716525/

相关文章:

ios - 编辑心情时表格 View 单元格保持未选中状态

ios - 如何在 SwiftUI 中创建两个大小相同的 "squares"占据整个屏幕宽度?

即使在安装 "Xcode Version 11.2.1 (11B500)"后,Xcode 仍会导致使用 UITextView 的应用程序崩溃

ios - 检测 Swift 中 UITextView 中的退格键

swift - 在 UITextField 中输入的每个数字周围绘制方框

ios - 翻转 NSScrollView 问题

android - 在 Cocos Creator cocos2d-x 中减小游戏大小

iphone - 为什么 NSString sizeWithFont : return the wrong size?

ios - 如何在图像周围绘制文字

ios - 可变大小的结构数组?