我正在开发一个自定义UIView
,它使用多个单独的NSLayoutManager
对象呈现文本。 (此视图具有超出内置文本视图类可支持的文本定位要求。)当布局文本为希伯来语时,我很难获得其中一个布局的正确垂直位置。我为这篇文章的篇幅道歉,但我希望尽可能多地包含相关细节。
问题
这是我想要完成的一个例子:
“2”的基线与希伯来字母“ו”(以自定义字体呈现)的基线很好地对齐。但是,如果我将“2”的文本切换为希伯来语数字(实际上是希伯来语字母“ב”,其在数字上下文中的值为2),它就像这样(“ב”太高):
此处仅更改为文本字符串。而不是"2"
,而是"\u{05b1}"
。我希望所有内容都在一个共同的基线上,并希望有任何解决问题的建议(所有希伯来语数字都会发生,而不仅仅是"\u{05b1}"
)。
代码
(我应该提一下,由于技术原因,我不能对数字和主要文本使用单个NSLayoutManager
。)我试图通过垂直移动渲染位置来对齐基线数字乘以字体上升的差异。这是计算班次的代码:
numberFont = UIFont.systemFont(ofSize: /* some size */)
offset = fullFont.ascender - numberFont.ascender
以下是我为数字创建NSLayoutManager
的方法:
var lbl = "2" // or "\u{05b1}"
let paraStyle = NSMutableParagraphStyle()
paraStyle.alignment = .center
let text = NSTextStorage(
string: lbl,
attributes: [NSFontAttributeName: numberFont,
NSParagraphStyleAttributeName: paraStyle]
)
let layout = NSLayoutManager()
text.addLayoutManager(layout)
let container = NSTextContainer(
size: CGSize(width: /* some fixed width */, height: bounds.height - offset)
)
container.lineFragmentPadding = 0
layout.addTextContainer(container)
let x = ... // irrelevant
let origin = CGPoint(x: x, y: bounds.minY + offset)
稍后,我使用以下方式呈现文本:
let range = layout.glyphRange(for: layout.textContainers[0])
layout.drawGlyphs(forGlyphRange: range, at: origin)
主要文本使用相同的逻辑处理,但没有offset
(当然也有不同的字体)。这适用于阿拉伯数字(例如“2”),但希伯来语数字(例如“ב”)则失败。
更多信息
对于上面的图片,字体大小(.pointSize
)和上升(.ascender
)属性为:
个尺寸:text = 14.3890409469604;数字= 8.63342465753425
上升:text = 16.159567469731; number = 8.2203017979452
我还生成了一些关于布局的诊断信息,但这些数字对我来说并没有多大意义。这是打印信息的代码:
size = text.size()
mgr = NSLayoutManager()
text.addLayoutManager(mgr)
container = NSTextContainer(
size: CGSize( width: CGFloat.greatestFiniteMagnitude,
height: CGFloat.greatestFiniteMagnitude))
container.lineFragmentPadding = 0
mgr.addTextContainer(container)
mgr.ensureLayout(for: container)
range = mgr.glyphRange(for: container)
print("label:", lbl)
print(" text size:", size)
print(" bounds:", mgr.boundingRect(forGlyphRange: range, in: container))
以下是两个文本(“2”和“\ u {05d1}”)的结果:
标签:2
文字大小:(5.3958904109589,10.3027782534247)
界限:(0.0,0.0,5.3958904109589,10.3027782534247)
label:ב
文字大小:(4.67931616438356,9.99459726027397)
界限:(-1.88208657534247,-0.578439452054793,9.5054005479452,9.77303671232876)
关于这个难题的几件事我:
NSAttributedString.size()
被打破了吗?