如何通过改变高亮颜色来突出CoreText?

我有一个UIView的子类,它实现了绘制CoreText的代码。 在应用程序中,UIView是在UIScrollView中绘制的。 以下是我当前在drawRect中使用的代码:呈现NSAttributedString:

CGContextRef context = UIGraphicsGetCurrentContext();

float viewHeight = self.bounds.size.height;
CGContextTranslateCTM(context, 0, viewHeight);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0, 1.0));

CGMutablePathRef path = CGPathCreateMutable();
CGRect bounds = CGRectMake(PADDING_LEFT, -PADDING_TOP, self.bounds.size.width-20.0, self.bounds.size.height);
CGPathAddRect(path, NULL, bounds);

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFMutableAttributedStringRef)attrString);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
CFRelease(framesetter);
CFRelease(path);
CTFrameDraw(frame, context);

在我的NSAttributedString中,我有一些文本属性来为文本着色。

我需要帮助的是概念上的,应该如何实现? 我很困惑所有绘制框架,图层等各种方法。我试图回顾几本书和其他资源,但我觉得我错过了一些基本的东西。

这是我的要求:

  • 显然,需要在取向改变的情况下重新绘制亮点。
  • 突出显示颜色需要能够以单个突出显示为基础以编程方式更改。
  • 对于性能来说,理想情况下,我不想在重新绘制一个高光的高亮颜色时重新绘制整个CoreText UIView。
  • 单个Rects必须能够组合在一起形成单个高光,因为高光可以覆盖超出单个CTLine的范围。
  • 最终,我想在CoreText视图上实现UIMenuController,所以我相信高亮必须绘制在CoreText UIView下面?
  • 我将不胜感激任何帮助。

    这是我迄今为止所尝试的:

    我添加了一个新的UIView作为UIScrollView的子视图来包含亮点。 然后我自己添加单独的UIViews。 当我创建虚拟“测试”突出显示时,它们在CoreText视图下正确显示。 我也可以轻松更改高亮颜色。 但是,当我从CoreText视图获取关于线条的实际信息以创建实际高光时,它将返回零线。 这可能是因为drawRect还没有完成绘图或其他东西?

    以下是一些问题:

  • 我是否应该将UIView作为子视图添加到UIScrollView,以包含每个单独高光部分的其他子视图的所有高亮部分? 然后,将每个高亮UIView存储在嵌套的NSArray中?
  • 如果我更改CoreText UIView下的高亮颜色,是否会导致整个UIView被重绘? 如果是这样,我怎么设计这个?
  • 确实,如果我想让CoreText UIView接收UIMenuController的输入,那我必须将高亮对象置于CoreText UIView之下?
  • 我见过这个开源项目:

    https://github.com/Cocoanetics/NSAttributedString-Additions-for-HTML

    这是令人惊讶的,但它比我需要的要复杂得多。 该代码使用CoreText呈现每个单独的字形运行并允许突出显示,这非常棒。 但是,我试图保持我的代码简单轻量。 我对CoreGraphics,CoreAnimation或CoreText知之甚少。

    我也看到了这个问题:

    核心文本 - 从NSRange获取像素坐标

    问题的答案提供了确定给定行中给定范围的Rect范围的调用。 我想我可以弄清楚这些电话。

    UPDATE

    这是我现在所做的。 我确信这是错误的,但这是我能找到的唯一方法,使其工作...

  • 创建一个UIView作为容器添加到UIScrollView作为子视图。
  • 将UIView传递给CoreTextView。 我还将一个字符串范围数组传递给CoreTextView,以指示应该突出显示哪些字符串。
  • 添加CoreTextView作为UIScrollView的子视图。 这样,UIView在CoreTextView下。
  • 在CoreTextView的drawRect:函数中,绘制了CoreText。 然后我调用一个函数来计算亮点。
  • 根据线检查每个NSRange,并计算线中每个匹配的CGRect。
  • CGRect用于创建一个新的UIView。 该UIView作为UIView容器的子视图添加。 它还添加到NSArray中,以便我可以跟踪它并根据需要更改单个高光的高光颜色。
  • 每次向容器添加突出显示或更改颜色时,都不会调用drawRect。 但是,我知道这不是一个理想的解决方案。 此解决方案的问题:

  • 当UIViewController在CoreTextView上调用setNeedsDisplay时,无法知道它何时完成绘图。 我仍然无法找到回调的方法,告诉ViewController可以继续下一个任务。
  • 通过将UIViews添加到其他容器UIView中,drawRect技术上是在其自己的矩形外绘制项目,我知道这是一个否定的项目。
  • 我相信这不是这样做的最高性能的方式,尽管它似乎工作得很好。

  • 你的基本想法对突出显示来说不算太坏。 我不知道这是否比在绘制时突出显示字形更容易,但这不是一个坏主意,并且可以轻松打开和关闭突出显示,所以这非常好。

    而不是创建大量视图,而是将您的核心文本放到CALayer 。 然后,您可以创建额外的高亮图层来放置文本。 这将所有内容都保存在单个视图中。 图层比视图便宜得多。 如果你只是试图做“突出显示”风格突出显示,那么你可以设置backgroundColorframe的图层,你就完成了。

    链接地址: http://www.djcxy.com/p/81937.html

    上一篇: How to highlight CoreText with changing highlight colors?

    下一篇: Graphical Bugs while programmatically creating UILabel, UITextField, etc