我对自定义UIView
的圆角和文本背景颜色有疑问。
基本上,我需要在自定义UIView中实现这样的效果(图像已附加-注意一侧的圆角):
我在想使用的方法是:
使用“核心文字”获取字形运行。
检查高光范围。
如果当前运行在突出显示范围内,则在绘制字形运行之前,绘制一个带有圆角和所需填充颜色的背景矩形。
绘制字形运行。
但是,我不确定这是否是唯一的解决方案(或者就此而言,这是否是最有效的解决方案)。
不能使用UIWebView
,因此我必须在自定义的UIView
中进行操作。
我的问题是,这是最好的使用方法,我走在正确的轨道上吗?还是我错过了重要的事情或以错误的方式去做?
最佳答案
我设法达到了上述效果,所以以为我会给出同样的答案。
如果有人对提高此效果有任何建议,请随时做出贡献。我将确保将您的答案标记为正确的答案。 :)
为此,您需要向NSAttributedString
添加一个“自定义属性”。
基本上,这意味着您可以添加任何键值对,只要它可以添加到NSDictionary
实例即可。如果系统无法识别该属性,则不执行任何操作。作为开发人员,您需要为该属性提供自定义实现和行为。
对于此答案,让我们假设我添加了一个名为@"MyRoundedBackgroundColor"
且值为[UIColor greenColor]
的自定义属性。
对于后续步骤,您需要对CoreText
如何完成工作有基本的了解。查看Apple's Core Text Programming Guide了解什么是帧/线/字形运行/字形等。
因此,步骤如下:
创建一个自定义UIView子类。
具有接受NSAttributedString
的属性。
使用该CTFramesetter
实例创建一个NSAttributedString
。
覆盖drawRect:
方法
从CTFrame
创建一个CTFramesetter
实例。
您需要提供一个CGPathRef
来创建CTFrame
。使该CGPath
与您要在其中绘制文本的框架相同。
获取当前图形上下文并翻转文本坐标系。
使用CTFrameGetLines(...)
,获取刚创建的CTFrame
中的所有行。
使用CTFrameGetLineOrigins(...)
,获取CTFrame
的所有行原点。
启动for loop
-为CTLine
数组中的每一行...
使用CTLine
将文本位置设置为CGContextSetTextPosition(...)
的开头。
使用CTLineGetGlyphRuns(...)
从CTRunRef
获取所有字形运行(CTLine
)。
启动另一个for loop
-为CTRun
数组中的每个glyphRun ...
使用CTRunGetStringRange(...)
获取运行范围。
使用CTRunGetTypographicBounds(...)
获取印刷范围。
使用CTLineGetOffsetForStringIndex(...)
获取运行的x偏移。
使用从上述函数返回的值来计算边界rect(我们称其为runBounds
)。
记住-CTRunGetTypographicBounds(...)
需要指向变量的指针来存储文本的“上升”和“下降”。您需要添加这些值以获得运行高度。
使用CTRunGetAttributes(...)
获取运行的属性。
检查属性字典是否包含您的属性。
如果您的属性存在,请计算需要绘制的矩形的边界。
核心文本在基线处具有行起点。我们需要从文本的最低点绘制到最高点。因此,我们需要针对下降进行调整。
因此,从我们在步骤16(runBounds
)中计算的边界矩形中减去下降。
现在有了runBounds
,我们知道要绘制的区域-现在我们可以使用任何CoreGraphis
/ UIBezierPath
方法来绘制并填充具有特定圆角的矩形。UIBezierPath
有一个名为bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:
的便利类方法,可让您舍入特定的角。您可以在第二个参数中使用位掩码指定拐角。
现在您已经填充了矩形,只需使用CTRunDraw(...)
绘制字形即可。
庆祝创建您的自定义属性的胜利-喝啤酒或其他东西! :D
关于检测属性范围是否跨越多个运行,当第一个运行遇到该属性时,可以获取自定义属性的整个有效范围。如果发现属性的最大有效范围的长度大于运行的长度,则需要在右侧绘制尖角(用于从左到右的脚本)。更多的数学运算将使您也可以检测下一行的高光拐角样式。 :)
附件是效果的屏幕截图。顶部的框是标准的UITextView
,为此我设置了attributedText。底部的框是使用上述步骤实现的框。为两个textView设置了相同的属性字符串。
再说一次,如果有比我使用的方法更好的方法,请告诉我! :D
希望这对社区有所帮助。 :)
干杯!
关于ios - NSAttributedString背景颜色和圆角,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48938139/