2011-04-29 72 views
17

我想知道何时文本被文本框架包装的视图是否有任何分隔符,可用于识别文本是否被包装。计算UITextView中的行数,按帧大小包装行数

例如,如果我的文本视图的宽度为50像素且文本超过该宽度,则会将文本包装到下一行。

我想计算我的文本视图中的行数。现在“\ n”和“\ r”没有帮助我。

我的代码是:

NSCharacterSet *aCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"\n\r"]; 
    NSArray *myArray = [textViewText componentsSeparatedByCharactersInSet:aCharacterSet]; 
    NSLog(@"%d",[myArray count]); 
+0

[Swift extension](http://stackoverflow.com/a/36626498/1634890) – 2016-04-14 14:42:20

回答

26

这种变化考虑如何包装你的线和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; 
4

使用此(其中_text_v是文本视图):

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

Hi最大。我尝试使用它,但对于我的文本视图中的8行数据,此方法返回的是5的计数。重要的是,我在数据中有7个\ n字符。 – Abhinav 2011-04-29 21:58:58

12

您需要使用lineHeight属性和字体lineHeight

Objective-C的

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

斯威夫特

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

我GETT正确的行数,希望它也能帮助你。

5

您需要考虑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行)

6

夫特延伸:

使用@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()

注意,如果由于某种原因,文本视图的字体是零,回报率将是零。

6

我在Apple的Text Layout Programming Guide中发现了这个问题的完美解决方案。下面是解苹果提供:

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对象作为参数的独立方法

+0

我想出这个答案100次,提供链接。观察:我用了一段时间,而不是“for”。在Swift3中没有更多的“传统”,无论如何,他们滥用它的方式显然很可怕。 – 2017-02-07 15:15:45

10

夫特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)