Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting CGRect for text in a UITextView for the purpose of highlighting with a CALayer

I am trying to draw a transparent CALayer in a UITextView in order to highlight matched text in a search.

I've figured out the correct way to do this, but still haven't found the correct coordinates. I need to find the origin of the text container. Right now, I get the textView's origin, and offset the layer's origin by that:

NSRange match = [[[self textView]text]rangeOfString:@"predict the future"];
NSRange glyphRange = [manager glyphRangeForCharacterRange:match actualCharacterRange:NULL];

CGRect textRect = [manager boundingRectForGlyphRange:glyphRange inTextContainer:[[self textView]textContainer]];

CGPoint textViewOrigin = self.textView.frame.origin;
textRect.origin.x += (textViewOrigin.x / 2);
textRect.origin.y += (textViewOrigin.y / 2);


CALayer* roundRect = [CALayer layer];
[roundRect setFrame:textRect];
[roundRect setBounds:textRect];

[roundRect setCornerRadius:5.0f];
[roundRect setBackgroundColor:[[UIColor blueColor]CGColor]];
[roundRect setOpacity:0.2f];
[roundRect setBorderColor:[[UIColor blackColor]CGColor]];
[roundRect setBorderWidth:3.0f];
[roundRect setShadowColor:[[UIColor blackColor]CGColor]];
[roundRect setShadowOffset:CGSizeMake(20.0f, 20.0f)];
[roundRect setShadowOpacity:1.0f];
[roundRect setShadowRadius:10.0f];

[[[self textView]layer]addSublayer:roundRect];

I get the following result if I move the text field, or if I don't divide the offsets by 2: The layer frame is off

I'd like to know if i'm on the right track and also how to find the NSTextContainer object's origin if so.

like image 851
Myron Slaw Avatar asked Jan 12 '23 16:01

Myron Slaw


1 Answers

To position the layer correctly, you only have to add self.textView.textContainerInset.top to textRect.origin.y, not the text view's origin.

But as I said in the comment, it won't work nicely if your match is across two lines. You may want to set the background colour of the matched range to highlight it, (using the attributedText property), but then you can't add the rounded corners or shadow.

like image 168
Jesús A. Álvarez Avatar answered Jan 26 '23 21:01

Jesús A. Álvarez