如何读取UITextView中的行数

24
我在我的视图中使用了UITextView,需要计算文本视图包含的行数。我使用以下函数来读取'\n'。但是,当我连续输入字符时,不会得到新的换行符号。如何在更改行时读取新字符而无需按回车键?有没有人知道如何做...请分享一下。 我遵循这个链接 Link
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range 
 replacementText:(NSString *)text
{
    // Any new character added is passed in as the "text" parameter
    if ([text isEqualToString:@"\n"]) {
        // Be sure to test for equality using the "isEqualToString" message
        [textView resignFirstResponder];

        // Return NO so that the final '\n' character doesn't get added
        return NO;
    }
    // For any other character return YES so that the text gets added to the view
    return YES;
}

3
BOOL 的两个取值不是 TRUEFALSE,而是 YESNO - BoltClock
4个回答

27

iOS 7 中应该是这样的:

float rows = (textView.contentSize.height - textView.textContainerInset.top - textView.textContainerInset.bottom) / textView.font.lineHeight;

13
回答很好,但在某些字体大小上是错误的,因为结果被转换为整数。为避免错误,请四舍五入:float rows = round((textView.contentSize.height - textView.textContainerInset.top - textView.textContainerInset.bottom) / textView.font.lineHeight); - Ricardo Sanchez-Saez
我认为 floorround 更好,因为 contentSize 总是大于 textViewtext 容量。@RicardoSánchez-Sáez - DawnSong
如果我没记错的话,当我写下这条评论时情况并非如此,但也许现在iOS方面已经改进了这一点。 - Ricardo Sanchez-Saez

26

您可以查看UITextView的contentSize属性以获取文本的像素高度,并除以UITextView字体的行高间距,以获取总UIScrollView中文本行数(包括换行和分行文本)。


63
numLines = textView.contentSize.height / textView.font.lineHeight; - nacho4d
1
我用 numLines = textView.contentSize.height/textView.font.leading 解决了这个问题。 - santosh
8
textView.font.leading在iOS4中已被弃用,请使用textView.font.lineHeight - cnotethegr8
2
这个答案只有大约75%的准确率。我计算了行数(从空开始+numLines++),并将其与此计算进行比较,得到了以下结果:“true,false,true,true,false,true,true,true,false,true,true,false,true,true,true,false,true,true,false”。问题在于有一个顶部/底部插图会影响contentSize.height。请参见Soul Clinic的下一个答案(以及评论)。 - Ben Patch
2023年有没有解决方案?如果我在其中使用包含不同字体的属性字符串呢? - Kwnstantinos Nikoloutsos
2023年有没有解决方案?如果我在其中使用包含不同字体的属性字符串呢? - undefined

7
extension NSLayoutManager {
    var numberOfLines: Int {
        guard let textStorage = textStorage else { return 0 }

        var count = 0
        enumerateLineFragments(forGlyphRange: NSMakeRange(0, numberOfGlyphs)) { _, _, _, _, _ in
            count += 1
        }
        return count
    }
}

获取textView中的行数:

let numberOfLines = textView.layoutManager.numberOfLines

3
我觉得这应该是答案。考虑到UIKit为我们公开了布局管理器,所有其他解决方案都非常hacky... - George Green
除非是阿拉伯文本,否则这可能不会按照您的想法工作。我目前遇到一个问题,这在拉丁文本中完美运行,但在阿拉伯文本中却不行。 - Mars

-5

仅供参考...

另一种获得行数和内容的方法是使用与BoltClock答案编辑中提到的相同方法将行拆分为数组。

NSArray *rows = [textView.text componentsSeparatedByString:@"\n"];

您可以通过迭代数组来获取每行的内容,并且可以使用 [rows count] 来获取确切的行数。

需要注意的一点是,空行也会被计算在内。


2
如果文本由于换行而换行(即未按下回车键),则此方法无效。 - i_am_jorf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接