24

I am using UITextView In my View , I have requirement to count number of line contained by textview am using following function to read '\n' . However this works only when return key is pressed from keyboard , but in case line warapper (when i type continuous characters i wont get new line char ) . How do i read new char when line is changed without hitting return key ?? Anybody has nay idea how to .. please share it .. I am follwing this link 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;
}
Wayne Chen
  • 305
  • 2
  • 15
santosh
  • 504
  • 2
  • 6
  • 20

4 Answers4

27

In iOS 7, it should exactly be:

float rows = (textView.contentSize.height - textView.textContainerInset.top - textView.textContainerInset.bottom) / textView.font.lineHeight;
Soul Clinic
  • 1,189
  • 12
  • 18
  • 13
    Very nice answer but it is wrong at some font sizes due to the result being casted to int. Round it to avoid errors: `float rows = round( (textView.contentSize.height - textView.textContainerInset.top - textView.textContainerInset.bottom) / textView.font.lineHeight );` – Ricardo Sanchez-Saez Jun 09 '14 at 20:34
  • I don't think `round` is better than `floor`, because `contentSize` is always larger than `textView`'s `text` holds. @RicardoSánchez-Sáez – DawnSong Oct 26 '16 at 04:53
  • @DawnSong If I recall correctly, that was not the case when I wrote the comment, but perhaps they have improved this at the iOS side level now. – Ricardo Sanchez-Saez Nov 11 '16 at 23:21
26

You can look at the contentSize property of your UITextView to get the height of the text in pixels, and divide by the line height spacing of the UITextView's font to get the number of text lines in the total UIScrollView (on and off screen), including both wrapped and line broken text.

hotpaw2
  • 70,107
  • 14
  • 90
  • 153
  • 63
    numLines = textView.contentSize.height/textView.font.lineHeight; – nacho4d Aug 27 '10 at 17:46
  • 1
    i solved this one with numLines = textView.contentSize.height/textView.font.leading; – santosh Sep 06 '10 at 13:31
  • 8
    `textView.font.leading` is deprecated in iOS4. Use `textView.font.lineHeight`. http://developer.apple.com/library/ios/#documentation/uikit/reference/UIFont_Class/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/occ/instp/UIFont/leading – cnotethegr8 Jul 11 '13 at 05:56
  • 2
    This answer only works about 75% of the time. I kept a count of the number of lines (started empty + numLines++) and compared it against this calculation and got: "true, false, true, true, false, true, true, true, false, true, true, false, true, true, true, false, true, true, false" The problem is that there is a top/bottom inset which affects the contentSize.height. See the next answer by Soul Clinic (and the comment). – Ben Patch Feb 29 '16 at 16:59
  • In 2023 is there a solution for this? What if I am using attributed string inside which contains different fonts? – Kwnstantinos Nikoloutsos Jul 14 '23 at 14:31
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
    }
}

Get number of lines in textView:

let numberOfLines = textView.layoutManager.numberOfLines
Lizhen Hu
  • 814
  • 10
  • 16
  • 3
    I feel like this should be the answer. All the other solutions are very hacky considering UIKit exposes the layout manager for us... – George Green Jul 17 '18 at 12:11
  • Except that this might not work as you would think with arabic text. I'm currently facing an issue where this works perfectly with latin text, but not with arabic. – Mars Jun 14 '20 at 18:01
-5

Just for reference...

Another way you can get the number of lines and also the content, is splitting the lines in an array using the same method mentioned on the answer edit by BoltClock.

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

You can iterate through the array to get the content of each line and you can use the [rows count] to get the exact number of rows.

One thing to keep in mind is that empty lines will be counted as well.

Elkucho
  • 157
  • 1
  • 2
  • 9