Подсчет количества строк в UITextView, строк, обернутых размером кадра

Я хотел знать, когда текст обернут рамкой текстового представления, есть ли какой-либо разделитель, с помощью которого мы можем определить, был ли текст обернут или нет.

например, если мой текстовый вид имеет ширину 50 пикселей, а текст превышает ее, он переносит текст в следующую строку.

Я хотел подсчитать количество строк в моем текстовом представлении. Теперь "n "и" r " мне не помогают.

мой код:

NSCharacterSet *aCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"nr"];
    NSArray *myArray = [textViewText componentsSeparatedByCharactersInSet:aCharacterSet];
    NSLog(@"%d",[myArray count]);

8 ответов


эта вариация учитывает, как вы обертываете свои линии и максимальный размер UITextView, и может вывести более точную высоту. Например, если текст не подходит, он будет усечен до видимого размера, а если вы обернете целые слова (по умолчанию), это может привести к большему количеству строк, чем если вы делаете иначе.

UIFont *font = [UIFont boldSystemFontOfSize:11.0];
CGSize size = [string sizeWithFont:font 
                      constrainedToSize:myUITextView.frame.size 
                      lineBreakMode:UILineBreakModeWordWrap]; // default mode
float numberOfLines = size.height / font.lineHeight;

вам нужно использовать lineHeight свойства, и шрифт lineHeight:

С

int numLines = txtview.contentSize.height / txtview.font.lineHeight;

Свифт

let numLines = (txtview.contentSize.height / txtview.font.lineHeight) as? Int

Я получаю правильное количество строк, надеюсь это поможет вам также.


Swift 3:

let layoutManager:NSLayoutManager = textView.layoutManager
let numberOfGlyphs = layoutManager.numberOfGlyphs
var numberOfLines = 0
var index = 0
var lineRange:NSRange = NSRange()

while (index < numberOfGlyphs) {
    layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
    index = NSMaxRange(lineRange);
    numberOfLines = numberOfLines + 1
}

print(numberOfLines)

Я нашел идеальное решение этой проблемы в Apple Руководство По Программированию Макета Текста. Вот решение Apple предоставляет:

NSLayoutManager *layoutManager = [textView layoutManager];
unsigned numberOfLines, index;
unsigned numberOfGlyphs = [layoutManager numberOfGlyphs];
NSRange lineRange;

for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
    (void) [layoutManager lineFragmentRectForGlyphAtIndex:index effectiveRange:&lineRange];
    index = NSMaxRange(lineRange);
}

Это может быть легко записано в расширение для UITextView или как автономный метод, принимающий объект UITextView в качестве параметра


вам нужно рассмотреть textView.textContainerInset, также необходимо округлить вычисленное значение, так как номер строки определенно является целым числом

float rawLineNumber = (textView.contentSize.height - textView.textContainerInset.top - textView.textContainerInset.bottom) / textView.font.lineHeight;
int finalLineNumber = round(rawLineNumber)

в реальном случае, вы можете увидеть следующий результат rawLineNumber = 3.008099 finalLineNumber = 3 (3 строки)


Swift расширение:

используя @himanshu padia ответ

//MARK: - UITextView
extension UITextView{

    func numberOfLines() -> Int{
        if let fontUnwrapped = self.font{
            return Int(self.contentSize.height / fontUnwrapped.lineHeight)
        }
        return 0
    }

}

использование : yourTextView.numberOfLines()

имейте в виду, что если по какой-то причине шрифт текстового представления равен нулю, возврат будет равен нулю.


используйте это (где _text_v-ваш текстовый вид):

-(NSInteger) linesCount {
    return _text_v.contentSize.height/_text_v.font.lineHeight;
}

   func numberOfLines(textView: UITextView) -> Int {
    let layoutManager = textView.layoutManager
    let numberOfGlyphs = layoutManager.numberOfGlyphs
    var lineRange: NSRange = NSMakeRange(0, 1)
    var index = 0
    var numberOfLines = 0

    while index < numberOfGlyphs {
        layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
        index = NSMaxRange(lineRange)
        numberOfLines += 1
    }
    return numberOfLines
}

отлично работает для меня