【问题标题】:UITextView attributedText and syntax highlightingUITextView 属性文本和语法高亮
【发布时间】:2012-09-14 15:21:35
【问题描述】:

背景

因此,在 iOS 6 中,UITextView 可以采用属性字符串,这对于语法突出显示很有用。

我正在-textView:shouldChangeTextInRange:replacementText: 中做一些正则表达式模式,而且我经常需要更改已经输入的单词的颜色。除了重置属性文本之外,我没有看到其他选择,这需要时间。

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    //A context will allow us to not call -attributedText on the textView, which is slow.
    //Keep context up to date
    [self.context replaceCharactersInRange:range withAttributedString:[[NSAttributedString alloc] initWithString:text attributes:self.textView.typingAttributes]];

    // […]

    self.textView.scrollEnabled = FALSE;

    [self.context setAttributes:self.defaultStyle range:NSMakeRange(0, self.context.length)];
    [self refresh]; //Runs regex-patterns in the context
    textView.attributedText = self.context;

    self.textView.selectedRange = NSMakeRange(range.location + text.length, 0);
    self.textView.scrollEnabled = TRUE;

    return FALSE;
}

这在模拟器上运行正常,但在 iPad 3 上每个-setAttributedText 需要几百毫秒。

我向 Apple 提交了一个错误,请求能够改变属性文本。它被标记为重复,所以我看不出他们在说什么。

问题

更具体的问题: 如何更改 UITextView 中某些范围的颜色,使用大的多色文本,并具有足够好的性能以在每个 shouldReplaceText... 中执行此操作?

更广泛的问题: 如何在 iOS 6 中使用 UITextView 进行语法高亮?

【问题讨论】:

  • 我也在尝试突出显示我的网络扬声器应用程序中所说的文本。我以为我可以用 iOS6 轻松做到这一点,但是我找不到在特定范围内动态更改字符串颜色的 api。每次设置完整的属性文本都需要太多时间。
  • 我还向 Apple 提交了错误报告。我们需要类似这种方法的东西。 "textView_.attributedText addAttribute: value:font range:"
  • 是的,但我敢打赌,我们永远不会看到属性文本的可变版本,因为无论何时更改字符串,textView 都需要知道。我希望有一个更聪明的设置器,或者 UITextInput 的 -replaceRange: withText: 的属性版本
  • 听起来不错,我们现在只能将 nsstring 设置为“withText”,所以希望苹果能改变它。
  • 如果文本样式纯粹是装饰性的,您可能不必在用户每次输入内容时都更新整个文本视图。例如,您可以使用 NSTimer 更新属性文本,可能每 0.5 秒更新一次。

标签: uitextview syntax-highlighting ios6 nsattributedstring uitextviewdelegate


【解决方案1】:

attributeText 访问器必须往返于 HTML,因此对于语法高亮的文本视图实现而言,它确实不是最佳选择。在 iOS 6 上,您可能希望直接使用 CoreText。

【讨论】:

  • 我不知道 textView 的 HTML 是如何工作的,但是您可以像替换 DOM 中的一些文本并更新 textView 的文本一样简单地更改属性,不是吗?
【解决方案2】:

我的应用程序 Zap-Guitar (No-Strings-Attached) 遇到了同样的问题,我允许用户键入/粘贴/编辑自己的歌曲,并且应用程序会突出显示识别的和弦。

是的,苹果确实使用 html 编写器和解析器来显示属性文本。精彩的幕后解释可以在这里找到:http://www.cocoanetics.com/2012/12/uitextview-caught-with-trousers-down/

我为这个问题找到的唯一解决方案是不使用属性文本,这对于语法高亮来说是一种过度杀伤力。

相反,我使用纯文本恢复到良好的旧 UITextView,并在需要突出显示的文本视图中添加按钮。为了计算按钮框架,我使用了这个答案:How to find position or get rect of any word in textview and place buttons over that?

这将 CPU 使用率降低了 30%(给予或接受)。

这是一个方便的类别:

@implementation UITextView (WithButtons)
- (CGRect)frameForTextRange:(NSRange)range {
    UITextPosition *beginning = self.beginningOfDocument;
    UITextPosition *start = [self positionFromPosition:beginning offset:range.location];
    UITextPosition *end = [self positionFromPosition:start offset:range.length];
    UITextRange *textRange = [self textRangeFromPosition:start toPosition:end];
    CGRect rect = [self firstRectForRange:textRange];
    return [self convertRect:rect fromView:self.textInputView];
}

@end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    • 2014-12-05
    • 1970-01-01
    • 2014-12-14
    • 2011-06-14
    • 2013-01-18
    • 1970-01-01
    相关资源
    最近更新 更多