6

背景

因此,在 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 进行语法高亮?

4

2 回答 2

1

我的应用程序 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
于 2013-06-04T12:03:27.977 回答
0

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

于 2012-10-13T05:32:38.217 回答