Подтвердить что ты не робот

Создать 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, и окраска - единственное, что мне нужно.

Спасибо заранее.

4b9b3361

Ответ 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.

Например, например, те источники