Подсчет строк текста

Эта задача показывает, как считать число строк в блоке текста программно. Строки могут быть определены твердыми символами разрыва строки в текстовой строке, или они могут быть строками, сгенерированными текстовым механизмом создания макета, когда это обертывает текст для вписывания в текстовый контейнер.

Строки текста, определенного твердыми символами разрыва строки, такими как возврат каретки и новая строка, считаются абзацами текстовой системой. Т.е. текстовый механизм расположения генерирует фрагменты строки, измеренные для вписывания в текстовый контейнер, пока он не достигает твердого символа разрыва строки, таким образом, последний фрагмент обычно короче, чем контейнерная ширина. Однако, если строки размечаются в текстовый контейнер шире, чем самый длинный глиф, выполненный между твердыми символами разрыва строки, то каждый абзац является одной строкой.

Для подсчета числа твердых символов разрыва строки в текстовой строке можно использовать 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} диапазон, включающий весь текст.