可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I wanted to know when a text is wrapped by the frame of the text view is there any delimiter with which we can identify whether the text is wrapped or not.
For instance if my text view has a width of 50 px and text is exceeding that, it wraps the text to next line.
I wanted to count the number of lines in my text view. Now "\n" and "\r" are not helping me.
My code is:
NSCharacterSet *aCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"\n\r"];
NSArray *myArray = [textViewText componentsSeparatedByCharactersInSet:aCharacterSet];
NSLog(@"%d",[myArray count]);
回答1:
This variation takes into account how you wrap your lines and the max size of the UITextView
, and may output a more precise height. For example, if the text doesn't fit it will truncate to the visible size, and if you wrap whole words (which is the default) it may result in more lines than if you do otherwise.
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;
回答2:
You need to use the lineHeight
property, and font lineHeight
:
Objective-C
int numLines = txtview.contentSize.height / txtview.font.lineHeight;
Swift
let numLines = (txtview.contentSize.height / txtview.font.lineHeight) as? Int
I am getting correct number of lines, hope it help you also.
回答3:
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)
回答4:
I found the perfect solution to this problem in Apple's Text Layout Programming Guide. Here is the solution Apple provides:
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);
}
This could easily be written into an extension for UITextView, or as a standalone method taking in a UITextView object as a parameter
回答5:
You need to consider textView.textContainerInset, also need to round the calculated value since line number definitely is an integer
float rawLineNumber = (textView.contentSize.height - textView.textContainerInset.top - textView.textContainerInset.bottom) / textView.font.lineHeight;
int finalLineNumber = round(rawLineNumber)
In real case, you may see following result
rawLineNumber = 3.008099
finalLineNumber = 3 (3 lines)
回答6:
Swift extension:
Using @himanshu padia answer
//MARK: - UITextView
extension UITextView{
func numberOfLines() -> Int{
if let fontUnwrapped = self.font{
return Int(self.contentSize.height / fontUnwrapped.lineHeight)
}
return 0
}
}
Usage : yourTextView.numberOfLines()
be aware that if for some reason the font of the text view is nil, the return will be zero.
回答7:
Use this (where _text_v is your text view):
-(NSInteger) linesCount {
return _text_v.contentSize.height/_text_v.font.lineHeight;
}
回答8:
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
}
Working Fine for me
回答9:
Swift 4 version of Luke Chase's answer
let numberOfGlyphs = textView.layoutManager.numberOfGlyphs
var index = 0, numberOfLines = 0
var lineRange = NSRange(location: NSNotFound, length: 0)
while index < numberOfGlyphs {
textView.layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
index = NSMaxRange(lineRange)
numberOfLines += 1
}