1
I am using the below written method for getting the current selected line number of textView having attributed text. It works fine if last line is not blank. If last line goes blank this method is not giving a proper line number. 

Method : 

    - (NSInteger)getCurrentLineIndex{
        /*
         Get Current Line Inside UITextView
         */
        CGPoint cursorPosition = [self caretRectForPosition:self.selectedTextRange.start].origin;
        return (NSInteger)(cursorPosition.y / self.font.lineHeight);
    }

Is there any other way to get the current line index?


Fixed :  I already had mRangesArray in which each object gave a range of each line. Using those range objects and comparing with the selected range, I was able to fix the problem.

1) Get Ranges Array - (void)analyse { if (self.mRangesArray != nil) { [self.mRangesArray removeAllObjects]; } NSString *string = self.text; NSUInteger numberOfLines, index, stringLength = [string length];

    NSMutableArray *ranges = [NSMutableArray new];
    for (index = 0, numberOfLines = 0; index < stringLength; numberOfLines++)
    {
        NSRange range = [string lineRangeForRange:NSMakeRange(index, 0)];
        [ranges addObject:[NSValue valueWithRange:range]];
    }
    if (self.mRangesArray == nil) {
        self.mRangesArray = [[NSMutableArray alloc]init];
    }
    self.mRangesArray = ranges;
}

2) Compare Range Objects inside the RangesArray with the current selected Range
- (NSInteger)getCurrentLineIndex{ /* This method will be used to get mRangesArray */ [self analyse];

    /*
     Get Current Line Inside UITextView
     */

    NSRange selectedRange = self.selectedRange;

   __block NSInteger index = [self.mRangesArray count]-1;
    [self.mRangesArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSRange objectRange = [obj rangeValue];
        if (*stop == NO) {
            if (NSLocationInRange(selectedRange.location, objectRange)) {
                index = idx;
                *stop =YES;
                return;
              }
        }
    }];

}

Thanks guys for your help. Cheers :)

2 Answers2

1

EDIT: I've obviously ignored the currently selected part of your question. I'll still keep the code here in case someone needs it.

Have you tried counting the newline separator?

let str = "First\nSecond\nThird"
let tok = str.componentsSeparatedByString("\n")
print(tok.count) // Hopefully prints "3"
Akaino
  • 1,025
  • 6
  • 23
  • This is correct for getting total number of lines which I am getting properly. What I need is to get the line number or we can say as index which is having cursor currently. – user2130948 May 23 '16 at 14:06
  • Yeah, I got that. Just overread it. Anyway,you're going to get problems as you might have a variable font height. You're not getting the right line count without a proper line separator. If you are able to properly get your total number of lines you could count characters per line and divide it by your cursor position. Should work. Didn't try though, but I will! – Akaino May 23 '16 at 14:15
  • I got it. Have updated the above question with the solution.Thanks :) – user2130948 May 23 '16 at 19:58
  • Neat solution! I think I'm going to try that out too! – Akaino May 25 '16 at 06:45
0

Try this code it works

UIFont * fontNAme = [UIFont boldSystemFontOfSize:13.0]; 
CGSize size = [textView.text fontNAme  constrainedToSize:textView.frame.size  lineBreakMode:UILineBreakModeWordWrap]; 
int lineNumber = size.height / fontNAme .lineHeight;
NSLog(@"line = %d", lineNumber);