访问NSTextView指标

问题描述 投票:0回答:1

我有一个NSTextVIew,其中我仅显示标准字母中的等宽字符。因此,没有数字,特殊字符,表情符号等。每个字符都等于一个字形。在文本顶部,我需要绘制一些形状,并且我正在寻找一种从文本系统访问某些度量的方法:

  1. 从一个字符到下一个字符的距离
  2. 从一行到下一行的距离

请看图片以了解我的意思。

enter image description here

似乎没有可以直接使用的任何属性,或者至少我没有找到它们,所以现在我使用文本视图的layoutManager获取这些值:

对于第一个,我通过layoutmanager的boundingRect(forGlyphRange glyphRange: NSRange, in container: NSTextContainer) -> NSRect方法获得了两个相邻字符的包围式矩形,并减去了两个矩形的origin.x。

对于第二个字符,我可以使用相同的功能,但是随后我需要知道第二行中第一个字符的范围。或遍历所有字符,并且一旦包围的rect的origin.y改变,我在第二行上就有第一个字符,并且我可以计算两行之间的距离。

EDIT:这是使用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
1个回答
0
投票

[经过更多搜索和反复试验后,我发现distanceBetweenLines可以从字体指标和lineHeightMultiple计算出来,这是NSParagraphStyle的属性,但也可以在段落样式之外定义,即我做什么。

所以最后这有效:

let distanceBetweenLines = layoutManager.defaultLineHeight(for: myTextFont) * lineHeightMultiple

对于distanceBetweenCharacters,我还没有找到其他解决方案。

编辑

基于下面评论中@Willeke的建议,我现在如下计算distanceBetweenCharacters

let distanceBetweenCharacters = myTextFont.advancement(forCGGlyph: layoutManager.cgGlyph(at: 0)).width + myKerning
© www.soinside.com 2019 - 2024. All rights reserved.