【发布时间】:2020-06-04 21:27:27
【问题描述】:
我有一个NSTextVIew,其中我只显示标准字母表中的等距字符。所以没有数字、特殊字符、表情符号等。每个字符等于一个字形。在文本之上,我需要绘制一些形状,并且我正在寻找一种从文本系统访问一些指标的方法:
- 一个字符到下一个字符的距离
- 一行到下一行的距离
看图了解我的意思。
似乎没有任何可以直接使用的属性,或者至少我没有找到,所以我现在使用文本视图的layoutManager 来获取这些值:
对于第一个,我通过布局管理器的boundingRect(forGlyphRange glyphRange: NSRange, in container: NSTextContainer) -> NSRect 方法获得两个相邻字符的封闭矩形,并减去两个矩形的 origin.x。
对于第二个,我可以使用相同的函数,但是我需要知道第二行第一个字符的范围。或者遍历所有字符,一旦封闭矩形的 origin.y 发生变化,我在第二行有第一个字符,我可以计算两行之间的距离。
编辑:这是使用 layoutManager 的可能代码:
typealias TextMetrics = (distanceBetweenCharacters: CGFloat, distanceBetweenLines: CGFloat)
var metrics: TextMetrics = self.textMetrics() // need to update when text changes
func textMetrics() -> TextMetrics {
guard let lm = self.layoutManager,
let tc = self.textContainer
else { return (0,0)
}
var distanceBetweenCharacters: CGFloat = 0.0
var distanceBetweenLines: CGFloat = 0.0
if string.count > 2 {
let firstRect = lm.boundingRect(forGlyphRange: NSRange(location: 0, length: 1), in: tc)
let secondRect = lm.boundingRect(forGlyphRange: NSRange(location: 1, length: 1), in: tc)
distanceBetweenCharacters = secondRect.maxX - firstRect.maxX
for (index, _) in string.enumerated() {
let rect = lm.boundingRect(forGlyphRange: NSRange(location: index, length: 1), in: tc)
if rect.maxY > firstRect.maxY { // reached next line
distanceBetweenLines = rect.maxY - firstRect.maxY
break
}
}
}
return (distanceBetweenCharacters, distanceBetweenLines)
}
我还考虑从defaultParagraphStyle 获取这些信息,但如果我访问它,它是nil。
是否有其他更简单的方法来获取这些值?
【问题讨论】:
标签: swift macos nstextview nslayoutmanager