Подсчет строк текста
Эта задача показывает, как считать число строк в блоке текста программно. Строки могут быть определены твердыми символами разрыва строки в текстовой строке, или они могут быть строками, сгенерированными текстовым механизмом создания макета, когда это обертывает текст для вписывания в текстовый контейнер.
Строки текста, определенного твердыми символами разрыва строки, такими как возврат каретки и новая строка, считаются абзацами текстовой системой. Т.е. текстовый механизм расположения генерирует фрагменты строки, измеренные для вписывания в текстовый контейнер, пока он не достигает твердого символа разрыва строки, таким образом, последний фрагмент обычно короче, чем контейнерная ширина. Однако, если строки размечаются в текстовый контейнер шире, чем самый длинный глиф, выполненный между твердыми символами разрыва строки, то каждый абзац является одной строкой.
Для подсчета числа твердых символов разрыва строки в текстовой строке можно использовать NSString
методы getLineStart:end:contentsEnd:forRange:
и lineRangeForRange:
. Эти методы берут диапазон символов в качестве ввода и возвращают строки, содержащие тот диапазон. Они определяют строки как диапазоны символов, заканчивающиеся в возврате каретки, новой строке, возврате каретки и новой строке вместе (в том порядке, часто называемом CRLF), и символы Unicode для разделителя строки и разделителя абзацев. Например, код в Перечислении 1 помещает в numberOfLines
число строк в NSString
переменная string
.
Перечисление 1 считая переносы строк
NSString *string; |
unsigned numberOfLines, index, stringLength = [string length]; |
for (index = 0, numberOfLines = 0; index < stringLength; numberOfLines++) |
index = NSMaxRange([string lineRangeForRange:NSMakeRange(index, 0)]); |
Этот компактный фрагмент кода начинается путем создания диапазона, содержащего только первый символ в строке. lineRangeForRange:
метод возвращает строку, содержащую тот символ как диапазон, включающий твердый символ разрыва строки (или символы). NSMaxRange
функционируйте возвращает индекс первого символа в следующей строке, которая является значением, присвоенным index
. numberOfLines
переменные инкременты, и for
повторения цикла, до index
больше, чем длина string
, в которой точке numberOfLines
содержит число строк в string
, как определено твердыми символами разрыва строки.
Для подсчета строк сгенерированными текстовым механизмом создания макета, когда это обертывает текст для вписывания в текстовый контейнер можно получить информацию от менеджера по расположению, как показано в Перечислении 2.
Строки подсчета перечисления 2 обернутого текста
NSLayoutManager *layoutManager = [textView layoutManager]; |
unsigned numberOfLines, index, numberOfGlyphs = |
[layoutManager numberOfGlyphs]; |
NSRange lineRange; |
for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){ |
(void) [layoutManager lineFragmentRectForGlyphAtIndex:index |
effectiveRange:&lineRange]; |
index = NSMaxRange(lineRange); |
} |
Этот код предполагает, что у Вас есть ссылка на текстовое представление, сконфигурированное с менеджером по расположению, текстовым хранением и текстовым контейнером. Текстовое представление возвращает ссылку на менеджера по расположению, тогда возвращающего число глифов для всех символов в его связанном текстовом хранении, выполняя генерацию глифа при необходимости. for
цикл тогда начинает излагать текст и считать получающиеся фрагменты строки. NSLayoutManager
метод lineFragmentRectForGlyphAtIndex:effectiveRange:
расположение сил строки, содержащей глиф в индексе, передало ему. Метод возвращает прямоугольник, занятый фрагментом строки (сюда проигнорированный) и, ссылкой, диапазоном глифов в строке после расположения. После того, как метод вычисляет строку, NSMaxRange
функционируйте возвращает индекс одно большее, чем максимальное значение в диапазоне, т.е. индексе первого глифа в следующей строке. numberOfLines
переменные инкременты, и for
повторения цикла, до index
больше, чем число глифов в тексте, в который точка numberOfLines
содержит число строк, следующих из процесса создания макета, как определено переходом на новую строку.
Эта стратегия вызывает расположение всего текста, содержавшегося в текстовом объекте хранения, и вычисляет число строк, требуемых размечать его, независимо от числа текстовых заполненных контейнеров или текстовые представления, требуемые вывести на экран его. Для получения числа строк на единственной странице (который моделируется текстовым контейнером) Вы использовали бы NSLayoutManager
метод glyphRangeForTextContainer:
и ограничьте подсчет строки for
цикл к тому диапазону, а не {0, numberOfGlyphs}
диапазон, включающий весь текст.