Создать UITextRange из NSRange
Мне нужно найти пиксельный кадр для разных диапазонов в текстовом виде. Я использую - (CGRect)firstRectForRange:(UITextRange *)range;
для этого. Однако я не могу узнать, как на самом деле создать UITextRange
.
В основном это то, что я ищу:
- (CGRect)frameOfTextRange:(NSRange)range inTextView:(UITextView *)textView {
UITextRange*range2 = [UITextRange rangeWithNSRange:range]; //DOES NOT EXIST
CGRect rect = [textView firstRectForRange:range2];
return rect;
}
Apple заявляет, что для принятия протокола UITextInput
требуется подкласс UITextRange
и UITextPosition
. Я этого не делаю, но в любом случае я попытался выполнить код примера doc и передать подкласс в firstRectForRange
, из-за которого произошел сбой.
Если есть более простой способ добавить в текстовое изображение разные цветные UILables
, скажите, пожалуйста. Я пробовал использовать UIWebView с content editable
, установленным в TRUE, но я не люблю общаться с JS, и окраска - единственное, что мне нужно.
Спасибо заранее.
Ответы
Ответ 1
Вы можете создать текстовый диапазон с помощью метода textRangeFromPosition:toPosition
. Этот метод требует двух позиций, поэтому вам нужно вычислить позиции для начала и конца вашего диапазона. Это делается с помощью метода positionFromPosition:offset
, который возвращает позицию из другой позиции и смещения символа.
- (CGRect)frameOfTextRange:(NSRange)range inTextView:(UITextView *)textView
{
UITextPosition *beginning = textView.beginningOfDocument;
UITextPosition *start = [textView positionFromPosition:beginning offset:range.location];
UITextPosition *end = [textView positionFromPosition:start offset:range.length];
UITextRange *textRange = [textView textRangeFromPosition:start toPosition:end];
CGRect rect = [textView firstRectForRange:textRange];
return [textView convertRect:rect fromView:textView.textInputView];
}
Ответ 2
Это немного смешно, что кажется настолько сложным.
Простым "обходным решением" будет выбор диапазона (принимает NSRange), а затем чтение выбранногоTextRange (возвращает UITextRange):
- (CGRect)frameOfTextRange:(NSRange)range inTextView:(UITextView *)textView {
textView.selectedRange = range;
UITextRange *textRange = [textView selectedTextRange];
CGRect rect = [textView firstRectForRange:textRange];
return rect;
}
Это сработало для меня, даже если textView не является первым ответчиком.
Если вы не хотите, чтобы выбор сохранялся, вы можете либо reset selectedRange:
textView.selectedRange = NSMakeRange(0, 0);
... или сохранить текущий выбор и восстановить его позже
NSRange oldRange = textView.selectedRange;
// do something
// then check if the range is still valid and
textView.selectedRange = oldRange;
Ответ 3
В заголовок вопроса, это расширение Swift 2, которое создает UITextRange из NSRange.
Единственным инициализатором для UITextRange является метод экземпляра в UITextInput-протоколе, поэтому для расширения также требуется передать UITextInput, например UITextField или UITextView.
extension NSRange {
func toTextRange(textInput textInput:UITextInput) -> UITextRange? {
if let rangeStart = textInput.positionFromPosition(textInput.beginningOfDocument, offset: location),
rangeEnd = textInput.positionFromPosition(rangeStart, offset: length) {
return textInput.textRangeFromPosition(rangeStart, toPosition: rangeEnd)
}
return nil
}
}
Ответ 4
Swift 4 из Andrew Schreiber ответ для легкой копии/вставки
extension NSRange {
func toTextRange(textInput:UITextInput) -> UITextRange? {
if let rangeStart = textInput.position(from: textInput.beginningOfDocument, offset: location),
let rangeEnd = textInput.position(from: rangeStart, offset: length) {
return textInput.textRange(from: rangeStart, to: rangeEnd)
}
return nil
}
}
Ответ 5
Вот объяснение.
Объект UITextRange представляет диапазон символов в тексте контейнер; другими словами, он определяет начальный индекс и конечный индекс в строковой поддержке объекта ввода текста.
Классы, которые принимают протокол UITextInput, должны создавать пользовательские Объекты UITextRange для представления диапазонов в тексте, управляемом класс. Начальные и конечные индексы диапазона представленный объектами UITextPosition. Текстовая система использует оба Объекты UITextRange и UITextPosition для передачи текстового макета Информация. Существует две причины использования объектов для текстовых диапазонов а не примитивные типы, такие как NSRange:
В некоторых документах содержатся вложенные элементы (например, теги HTML и встроенные объекты), и вам нужно отслеживать как абсолютное положение, так и положение в видимом тексте.
Структура WebKit, на которой основана текстовая система iPhone, требует, чтобы текстовые индексы и смещения были представлены объектами.
Если вы используете протокол UITextInput, вы должны создать UITextRange, а также пользовательский подкласс UITextPosition.
Например, например, те источники