NSAttributedString背景颜色和圆angular

我有一个关于自定义UIView圆angular和文本背景颜色的问题。

基本上,我需要在自定义UIView中实现像这样的效果(图片附加 – 注意一侧的圆angular): 背景突出

我正在考虑使用的方法是:

  • 使用核心文本来获得字形运行。
  • 检查高亮范围。
  • 如果当前运行在高亮范围内,在绘制字形运行之前绘制一个带圆angular的背景矩形和所需的填充颜色。
  • 绘制字形运行。

不过,我不确定这是否是唯一的解决scheme(或者说这是否是最有效的解决scheme)。

使用UIWebView不是一个选项,所以我必须在自定义的UIView做到这一点。

我的问题是,这是最好的方法来使用,我在正确的轨道上? 或者我错过了一些重要的东西,或者错误地做了什么?

在此先感谢您的帮助! 🙂

干杯!

我设法达到了上述效果,所以我想我会给出同样的答案。

如果有人提出更有效的build议,请随时投稿。 我一定会把你的答案标记为正确的。 🙂

为此,您需要将一个“自定义属性”添加到NSAttributedString

基本上,这意味着你可以添加任何键值对,只要它是可以添加到NSDictionary实例的东西。 如果系统不能识别该属性,则不执行任何操作。 作为开发人员,由您提供该属性的自定义实现和行为。

为了这个答案的目的,让我们假设我已经添加了一个名为: @"MyRoundedBackgroundColor"的自定义属性,其值为[UIColor greenColor]

对于下面的步骤,您需要对CoreText如何完成任务有一个基本的了解。 查看Apple的Core Text Programming Guide了解框架/行/字形运行/字形等。

所以,这里是步骤:

  1. 创build一个自定义的UIView子类。
  2. 有一个属性来接受一个NSAttributedString
  3. 使用该NSAttributedString实例创build一个CTFramesetter
  4. 覆盖drawRect:方法
  5. CTFramesetter创build一个CTFrame实例。
    1. 您将需要提供一个CGPathRef来创buildCTFrame 。 使该CGPath与您想要绘制文本的框架相同。
  6. 获取当前的graphics上下文并翻转文本坐标系。
  7. 使用CTFrameGetLines(...) ,获取刚刚创build的CTFrame中的所有行。
  8. 使用CTFrameGetLineOrigins(...) ,获取CTFrameGetLineOrigins(...)所有行源。
  9. 开始for loopCTLine数组中的每一行…
  10. 使用CGContextSetTextPosition(...)将文本位置设置为CTLine的开头。
  11. 使用CTLineGetGlyphRuns(...)CTLineGetGlyphRuns(...)获取所有的Glyph运行( CTRunRef )。
  12. 启动另一个for loop – CTRun数组中的每个CTRun
  13. 使用CTRunGetStringRange(...)获取运行的范围。
  14. 使用CTRunGetTypographicBounds(...)获取印刷边界。
  15. 使用CTLineGetOffsetForStringIndex(...)获取运行的x偏移量。
  16. 使用从上述函数返回的值计算边界矩形(让我们称之为runBounds )。
    1. 请记住 – CTRunGetTypographicBounds(...)需要指向variables的指针来存储文本的“上升”和“下降”。 你需要添加这些来获得运行高度。
  17. 使用CTRunGetAttributes(...)获取运行的属性。
  18. 检查属性字典是否包含您的属性。
  19. 如果您的属性存在,计算需要绘制的矩形的边界。
  20. 核心文本在基线处具有线条起点。 我们需要从文本的最低点拉到最高点。 因此,我们需要调整下降。
  21. 因此,从我们在步骤16( runBounds )中计算出的边界runBounds减去下降。
  22. 现在我们有了runBounds ,我们知道我们要绘制的区域 – 现在我们可以使用任何CoreGraphis / UIBezierPath方法绘制和填充具有特定圆angular的矩形。
    1. UIBezierPath有一个方便的类方法叫做bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:让我们围绕特定的angular落。 您可以使用第二个参数中的位掩码来指定angular点。
  23. 现在您已经填充了矩形,只需使用CTRunDraw(...)绘制字形运行CTRunDraw(...)
  24. 庆祝创造您的习惯属性的胜利 – 喝一杯啤酒或其他东西! :d

关于检测属性范围扩展到多次运行,当第一次运行遇到属性时,可以获得自定义属性的整个有效范围。 如果发现属性的最大有效范围的长度大于运行的长度,则需要在右侧绘制尖angular(对于从左到右的脚本)。 更多math可以让你检测下一行的高光angular落风格。 🙂

附加是效果的截图。 顶部的框是一个标准的UITextView ,为此我设置了属性UITextView 。 底部的方框是使用上述步骤实现的方框。 两个textView都设置了相同的属性string。 带圆角的自定义属性

再次,如果有比我使用的更好的方法,请让我知道! :d

希望这有助于社区。 🙂

干杯!