Получение CGRect для текста в UITextView с целью выделения с помощью CALayer
Я пытаюсь нарисовать прозрачный CALayer в UITextView, чтобы выделить совпадающий текст в поиске.
Я нашел правильный способ сделать это, но все еще не нашел правильные координаты. Мне нужно найти происхождение текстового контейнера. Прямо сейчас я получаю источник textView и смещаю источник слоя на это:
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];
Я получаю следующий результат, если переместить текстовое поле или не разделю смещения на 2:
Я хотел бы знать, нахожусь ли я на правильном пути, а также как найти источник объекта NSTextContainer, если это так.
2 ответа
Чтобы правильно расположить слой, вам нужно только добавить self.textView.textContainerInset.top
в textRect.origin.y
, а не происхождение текстового представления.
Но, как я сказал в комментарии, это не сработает, если ваше совпадение пересекает две строки. Вы можете установить цвет фона соответствующего диапазона, чтобы выделить его (используя attributedText
свойство), но тогда вы не можете добавить закругленные углы или тень.
[textView textContainerInset]
Использование источника текстового представления не будет работать, потому что вставки могут быть изменены где-то еще. Примером может служить случай, если для свойства displayAdjustsScrollViewInsets родительского контроллера установлено значение YES или выполняется какая-либо пользовательская компоновка текстового контейнера.
UIEdgeInsets textContainerInset = [[self textView]textContainerInset];
textRect.origin.x += textContainerInset.left;
textRect.origin.y += textContainerInset.top;
Это решение для получения правильной геометрии, но не в том случае, если текст занимает две строки.