NSAttributedString背景颜色和圆角(NSAttributedString backg

2019-09-01 21:24发布

我有一个关于圆角和自定义文字背景色问题UIView

基本上,我需要实现这样的效果(附加图像 - 注意到在一侧圆角)在一个自定义的UIView:

我想使用的方法是:

  • 使用核心文本得到字形运行。
  • 检查加亮区范围。
  • 如果当前游程是高亮范围内时,绘制字形运行之前绘制一个带圆角和所需的填充颜色的背景矩形。
  • 绘制字形运行。

但是,我不知道这是否是唯一的解决办法(或就此而言,这是否是最有效的解决方案)。

使用UIWebView是不是一种选择,所以我必须做一个定制UIView

我的问题的存在,这就是用最好的方法,而我是在正确的轨道上? 还是我失去了一些重要的东西或去约了错误的方式?

Answer 1:

我设法达到上述效果,所以以为我会发布了同样的答案。

如果任何人有关于使这个更有效的任何建议,请随时作出贡献。 我一定会来标记你的答案是正确的。 :)

这样做,你需要一个“自定义属性”添加到NSAttributedString

基本上,这是什么意思是,你可以添加任何键值对,只要它的东西,你可以添加到一个NSDictionary实例。 如果系统无法识别的属性,它什么都不做。 它是你的,作为开发商,提供该属性的定制实现和行为。

对于这个答案的目的,让我们假设我也添加了一个自定义属性: @"MyRoundedBackgroundColor"与值[UIColor greenColor]

对于接下来的步骤中,你需要有一个如何一个基本的了解CoreText得到的东西做。 看看苹果的核心文本编程指南理解什么是帧/线/字形运行/字形等。

所以,这里的步骤:

  1. 创建一个自定义UIView子类。
  2. 对受理的属性NSAttributedString
  3. 创建CTFramesetter使用NSAttributedString实例。
  4. 重写drawRect:方法
  5. 创建CTFrame从实例CTFramesetter
    1. 你需要给出一个CGPathRef创建CTFrame 。 作出这样的CGPath是一样的,你要绘制文本框。
  6. 获取当前图形上下文和翻转文字的坐标系。
  7. 使用CTFrameGetLines(...)获得在所有行CTFrame刚刚创建。
  8. 使用CTFrameGetLineOrigins(...)让所有的行起源CTFrame
  9. 启动一个for loop -对于数组中的每一行CTLine ...
  10. 设置文本位置到开始CTLine使用CGContextSetTextPosition(...)
  11. 使用CTLineGetGlyphRuns(...)获得所有铭文奔跑( CTRunRef从) CTLine
  12. 启动另一个for loop的阵列中的每个glyphRun - CTRun ...
  13. 获取使用运行的范围CTRunGetStringRange(...)
  14. 获取使用印刷界CTRunGetTypographicBounds(...)
  15. 看一下X使用运行偏移CTLineGetOffsetForStringIndex(...)
  16. 计算边界矩形(姑且称之为runBounds )使用来自上述函数的返回值。
    1. 记住- CTRunGetTypographicBounds(...)需要指针变量来存储“上升”和文本的“血统”。 您需要添加这些获得运行高度。
  17. 获得使用运行属性CTRunGetAttributes(...)
  18. 检查属性字典包含您的属性。
  19. 如果你的属性存在,计算出需要绘制矩形的边界。
  20. 核心文本有在基准线的起源。 我们需要从文本到最高点的最低点绘制。 因此,我们需要调整的后裔。
  21. 因此,减去我们在步骤16(计算的边界RECT下降runBounds )。
  22. 现在,我们有runBounds ,我们知道我们要画什么区-现在我们可以使用任何的CoreGraphis / UIBezierPath方法绘制并填写具体的圆角一个矩形。
    1. UIBezierPath有一个称为方便类方法bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:它可以让您全面具体的角落。 您指定使用位掩码在第二个参数的角落。
  23. 现在,你已经填补了矩形,简单地画使用运行字形CTRunDraw(...)
  24. 为庆祝在创建了您的自定义属性的胜利 - 喝啤酒什么的! :d

对于检测到的属性范围扩展多次运行,则可以在第一次运行遇到属性得到整个有效范围自定义属性。 如果您发现最大有效射程你的属性的长度比你跑的长度,你需要画右边尖角(对于从左到右脚本)。 更多的数学会让你发现的亮点角样式下一行也是如此。 :)

附上的效果截图。 在箱体顶部是一个标准UITextView ,为此,我已经设置了attributedText。 底部的箱是已经使用上述步骤实现的一个。 同样的属性串已被设置为两个textViews。

同样,如果有比我使用了一个更好的办法,请不要让我知道! :d

希望这有助于社会。 :)

干杯!



文章来源: NSAttributedString background color and rounded corners