Подсчет количества строк в 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
}
отлично работает для меня