У меня есть NSTextVIew
, в котором я показываю только одинарные символы из стандартного алфавита. Так что никаких цифр, специальных символов, смайликов и т. Д. c. Каждый символ равен одному глифу. Поверх текста мне нужно нарисовать несколько фигур, и я ищу способ доступа к некоторым метрикам из текстовой системы:
- расстояние от одного символа до следующего
- расстояние от одной линии до следующей
См. Картинку, что я имею в виду.
Там у меня нет свойств, которые я могу использовать напрямую, или, по крайней мере, я их не нашел, поэтому теперь я использую текстовое представление layoutManager
, чтобы получить эти значения:
Для первого Я получаю заключающие строки для двух смежных символов с помощью метода boundingRect(forGlyphRange glyphRange: NSRange, in container: NSTextContainer) -> NSRect
компоновщика и вычитаю origin.x для обеих сторон.
Для второго я мог бы использовать ту же функцию, но затем я нужно знать диапазон для первого символа во второй строке. Или перебрать все символы, и как только 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
.
Возможно, есть другой, более простой способ получить эти значения?