Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextView get the current line

Is there a way (crazy hacks welcome) to get the current line as a string of a UITextView? This would include word wrapping, etc. For example, in this case:

enter image description here

The method would return "stack overflow. Isn't it great? I" because that is the current line based on the cursor.

It could also return "This is a test I made for" or "think so", based on the position of the cursor. I have tried working with both the UITextView methods and those of UITextInput protocol.

EDIT:

Here is the code I have attempted to use. The reason I need to find the string is to get it's length, so this is why you'll see UI based code.

NSRange location = self.textView.selectedRange;
NSString *searchString = [self.textView.text substringWithRange:NSMakeRange(0, location)];
CGSize currentStringDimensions = [searchString sizeWithFont:self.textView.font constrainedToSize:CGSizeMake(self.textView.frame.size.width, self.textView.frame.size.height) lineBreakMode:NSLineBreakByWordWrapping];    
float numberOfRows = (currentStringDimensions.width/(self.textView.frame.size.width));
float left = (float)(numberOfRows - (int)numberOfRows) * (self.textView.frame.size.width);

This doesn't work, however. I think it might have something to with words being wrapped or the differently sized characters, but the left value is inconsistent or off after the first line.

like image 259
roozbubu Avatar asked Jul 09 '13 20:07

roozbubu


2 Answers

The following code solution seem to be working. The "self" in this code refers to an instance of UITextView.

- (NSString *) getLineString:(NSRange)range
{
    NSLayoutManager *manager = self.layoutManager;

    // Convert it to a glyph range
    NSRange matchingGlyphRange = [manager glyphRangeForCharacterRange:range actualCharacterRange:NULL];

    // line fragment rect at location range
    CGRect rect = [manager lineFragmentRectForGlyphAtIndex:matchingGlyphRange.location effectiveRange:nil];

    // obtain the line range for the line fragment rect
    NSRange lineRange = [manager glyphRangeForBoundingRect:rect inTextContainer:self.textContainer];

    // extract the string out from lineRange
    return [self.text substringWithRange:lineRange];
}

// ... later
NSLog(@"line %@", [self getLineString:self.selectedRange]);
like image 129
Benny Khoo Avatar answered Oct 29 '22 22:10

Benny Khoo


This worked for me (self = the UITextView)

func getLineString() -> String {
    return (self.text! as NSString).substringWithRange((self.text! as NSString).lineRangeForRange(self.selectedRange))
}
like image 20
Gil Avatar answered Oct 29 '22 22:10

Gil