如何通过更改高亮颜色突出显示CoreText? [英] How to highlight CoreText with changing highlight colors?

查看:97
本文介绍了如何通过更改高亮颜色突出显示CoreText?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a subclass of UIView that implements code to draw CoreText. In the application, that UIView is drawn inside a UIScrollView. Here is the code that I currently use in drawRect: to render an 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中,我有一些文本属性可以为文本着色。

In my NSAttributedString, I have certain text attributes to color the text.

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

What I need help with is conceptually, how should this be accomplished? I am confused by all the various methods of drawing frames, layers, etc. I have tried to review several books and other resources, but I feel like I'm missing some basic stuff.

以下是我的要求:


  1. 明显需要在更改方向时重新绘制到新位置。

  2. 突出显示颜色需要能够以个别突出显示的方式进行编程。

  3. 理想情况下,我不想重新绘制当我只更改一个高光的高亮颜色时,整个CoreText UIView。

  4. 单个Rects必须能够组合在一起形成一个高光,因为高光可以覆盖超出范围的范围单个CTLine。

  5. 最后,我想在CoreText视图上实现UIMenuController,所以我相信必须在CoreText UIView下面绘制高光?

  1. Highlights obviously need to be redrawn to the new location on a change of orientation.
  2. Highlight color needs to be able to be changed programmatically on an individual highlight basis.
  3. Ideally for performance, I don't want to have to re-draw the entire CoreText UIView when I just change the highlight color of one highlight.
  4. The individual Rects must be able to be grouped together to form a single highlight since highlights can cover a range that goes beyond a single CTLine.
  5. Eventually, I want to implement UIMenuController on CoreText view so I believe that the highlights must be drawn underneath the CoreText UIView?

我非常感谢任何屁股是的。

I would greatly appreciate any assistance.

这是我到目前为止所尝试的:

Here is what I have tried so far:

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

I added a new UIView as a subview to the UIScrollView to contain the highlights. I then add individual UIViews for the highlights themselves. When I create dummy "test" highlights, they appear correctly under the CoreText view. I can also easily change the highlight color. However, when I go to acquire actual information about the lines from the CoreText view to create real highlights, it returns zero lines. Could this be because drawRect isn't finished drawing yet or something else?

以下是一些问题:


  1. 我是否应该将UIView作为子视图添加到UIScrollView中,以包含所有突出显示以及每个突出显示的其他子视图?然后,将每个高亮UIView存储在嵌套的NSArray中?

  2. 如果我更改CoreText UIView下方高亮的颜色,是否会导致整个UIView被重绘?如果是这样,我该如何设计?

  3. 如果我希望CoreText UIView接收UIMenuController的输入,我必须将高亮对象放在CoreText UIView下面?

我见过这个开源项目:

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

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

This is amazing what it can do, but is far more complex and detailed than I need. The code renders each individual glyph run using CoreText and permits highlighting, which is awesome. However, I am trying to keep my code simple and lightweight. I know very little about CoreGraphics, CoreAnimation or CoreText.

我也看到过这个问题:

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

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

The answer to the question provides the calls to determine the bounds of a Rect for a given range in a given line. I think I can figure out those calls.

更新

这是什么我现在做了。我确定这是错误的,但这是我能找到它的唯一方法...

Here is what I have done now. I'm sure this is wrong, but it is the only way I could find to make it work...


  1. 创建一个UIView为要作为子视图添加到UIScrollView的容器。

  2. 将UIView传递给CoreTextView。我还将一个字符串范围数组传递给CoreTextView,以指示应突出显示哪些字符串。

  3. 将CoreTextView添加为UIScrollView的子视图。这样,UIView就在CoreTextView下面。

  4. 在CoreTextView的drawRect:函数中,我绘制了CoreText。然后我调用一个函数来计算亮点。

  5. 每个NSRange都会根据行进行检查,并且计算行中每个匹配项的CGRect。

  6. CGRect用于创建新的UIView。 UIView被添加为UIView容器的子视图。它也被添加到NSArray中,以便我可以跟踪它并根据需要更改单个突出显示的突出显示颜色。

  1. Create a UIView as a container to add to the UIScrollView as a subview.
  2. Pass UIView to CoreTextView. I also pass an array of string ranges to CoreTextView to indicate which strings should be highlighted.
  3. Add CoreTextView as a subview of UIScrollView. That way, UIView is underneath CoreTextView.
  4. In the drawRect: function of CoreTextView, I draw the CoreText. I then call a function to calculate the highlights.
  5. Each NSRange is checked against the lines and the CGRect of each match in the line is calculated.
  6. CGRect is used to create a new UIView. That UIView is added as a subView of the UIView container. It is also added to an NSArray so that I can keep track of it and change the highlight color of an individual highlight as needed.

每次将高亮显示添加到容器或更改颜色时,都不会调用drawRect。但是,我知道这不是一个理想的解决方案。此解决方案的问题:

This does not call drawRect each time a highlight is added to the container or color changed. However, I know this isn't an ideal solution. Problems with this solution:


  1. 当UIViewController在CoreTextView上调用setNeedsDisplay时,无法知道何时完成绘图。我仍然找不到一种方法来做一个回调来告诉ViewController可以继续下一个任务。

  2. 通过将UIViews添加到另一个容器UIView,drawRect在技术上是在我自己的rect之外绘制项目,我知道这是不是没有。

  3. 我确信这不是最有效的方法,尽管它看起来确实很漂亮好吧。


推荐答案

你的基本想法对于突出显示来说并不算太糟糕。我不知道它是否比在绘制时突出显示字形更容易,但这并不是一个坏主意,并且可以很容易地打开和关闭突出显示,所以这很不错。

Your basic idea isn't too bad for highlighting. I don't know if it's really easier than just highlighting the glyphs while you draw, but it's not a bad idea, and makes it easy to turn on and off highlighting, so that's pretty nice.

而不是创建大量视图,而是将您的核心文本放到 CALayer 上。然后,您可以创建其他突出显示图层以放置文本。这样可以将所有内容保留在单个视图中。图层比视图便宜得多。如果你只是想做荧光笔式的高亮显示,那么你可以设置 backgroundColor frame 你已经完成了这些层次。

Rather than creating lots of views, put your Core Text onto a CALayer instead. Then you can create additional highlighting layers to put over the text. This keeps everything inside of a single view. Layers are much cheaper than views. If you're just trying to do "highlighter" style highlighting, then you can just set the backgroundColor and frame for the layers and you're done.

这篇关于如何通过更改高亮颜色突出显示CoreText?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆