UITextView (редактирование) - обнаружение события следующей строки - PullRequest
6 голосов
/ 02 февраля 2011

У меня есть UITextView, который можно редактировать.Теперь у меня есть требование, которое требует от меня (как и когда я продолжаю печатать) относительно того, когда начинается следующая строка (возможно, из-за того, что я нажал клавишу возврата или автоматический перенос строки)Есть ли какое-либо уведомление, которое можно получить, чтобы выяснить, когда началась следующая строка при вводе?

Я пытался найти решения, чтобы узнать позиции курсора в текстовом представлении, но использование selectedRange и свойств местоположения для его определения мне не помогло.Нет никакой корреляции между значением местоположения и новой строкой.Значение местоположения просто увеличивается при наборе текста.Есть идеи?

Спасибо!

Ответы [ 7 ]

10 голосов
/ 02 февраля 2011

Следующий делегат вызывается всякий раз, когда в textView вводится новый текст.

Установите делегат для UITextView, затем кодируйте следующим образом

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
{
    if ( [text isEqualToString:@"\n"] ) {
        //Do whatever you want
    }
    return YES;
}
5 голосов
/ 03 августа 2015

Для Swift используйте это

previousRect = CGRectZero

 func textViewDidChange(textView: UITextView) {

        var pos = textView.endOfDocument
        var currentRect = textView.caretRectForPosition(pos)
        if(currentRect.origin.y > previousRect?.origin.y){
            //new line reached, write your code
        }
        previousRect = currentRect

    }

Для объектива C

CGRect previousRect = CGRectZero;
- (void)textViewDidChange:(UITextView *)textView{

    UITextPosition* pos = textView.endOfDocument;
    CGRect currentRect = [textView caretRectForPosition:pos];

    if (currentRect.origin.y > previousRect.origin.y){
            //new line reached, write your code
        }
    previousRect = currentRect;

}
2 голосов
/ 09 сентября 2011

Будет обнаруживать изменения строки от чего-либо до нажатия «return», возврата на обратную сторону для уменьшения количества строк, ввода до конца строки и переноса слов и т. Д. рекомендую не использовать жестко закодированные номера, как в моем примере ниже).

previousNumberOfLines = ((hiddenText.contentSize.height-37+21)/(21));//numbers will change according to font size
NSLog(@"%i", previousNumberOfLines);
1 голос
/ 14 апреля 2015

Я немного опоздал на вечеринку, но у меня было похожее требование, и после небольшого расследования я обнаружил, что ответ KingofBliss 'в сочетании с

-[id<NSLayoutManagerDelegate> layoutManager:shouldBreakLineByWordBeforeCharacterAtIndex:];
-[id<NSLayoutManagerDelegate> layoutManager:shouldBreakLineByHyphenatingBeforeCharacterAtIndex:];

сделал трюк для меня.

Вы можете установить любой объект в качестве делегата менеджера макета UITextView, например:

textView.textContainer.layoutManager.delegate = (id<NSLayoutManagerDelegate>)delegate

Надеюсь, это окажется полезным.

0 голосов
/ 28 мая 2019

Решение Сурава Гупты частично сработало для меня, однако у него было несколько ловушек, а именно то, что он неправильно вызывал целевой код, если редактирование происходило в середине текста (например: написание группы текста, перемещениекурсор в середину, а затем трижды нажмите клавишу возврата), а также обрабатывает события вставки, такие как вставка и исправление текста.В результате я провел некоторое собственное тестирование и обнаружил еще несколько условий, в которых можно предположить, что редактирование переместилось на следующую строку.

примечание: у этого подхода есть несколько ложных срабатываний, но я обнаружил, что это более терпимо, так как я использую это для передачи кода и, таким образом, излишнего размещения гораздо лучше, чем отсутствие ответа

Swift 5


private var previousRect:CGRect = CGRect.zero
private func checkIfReturnOrLineWrap(textView:UITextView) {
    let currentRect = textView.caretRect(for:textView.endOfDocument)
    if (currentRect.origin.y != previousRect.origin.y && (previousRect.origin.y != CGFloat.infinity || currentRect.origin.y > 0) ||
        currentRect.origin.y == CGFloat.infinity) {
        //React to the line change!
    }
    previousRect = currentRect
}

//MARK: UITextViewDelegate methods (be sure to hook up your textviews!)
func textViewDidChange(_ textView: UITextView) {
    checkIfReturnOrLineWrap(textView: textView)
}

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    checkIfReturnOrLineWrap(textView: textView)
    return true
}
0 голосов
/ 02 марта 2013
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
 replacementText:(NSString *)text
{

    if ([text isEqualToString:@"\n"]) {
        textView.text=[NSString stringWithFormat:@"%@\n",textView.text];
        // Return FALSE so that the final '\n' character doesn't get added
        return NO;
    }
    // For any other character return TRUE so that the text gets added to the view
    return YES;
}
0 голосов
/ 16 мая 2012

Добавьте второй скрытый вид текста к вашему виду. Реализуйте shouldChangeTextInRange для видимого текстового представления и установите текст в скрытом виде на новый текст. Сравните contentSize для нового и старого текста, чтобы обнаружить перенос слов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...