Поведение UITextViewDelegate при нажатой клавише обратного пробела

#iphone #cocoa-touch #ios #uitextview #uitextviewdelegate

#iPhone #cocoa-touch #iOS #uitextview #uitextviewdelegate

Вопрос:

Я столкнулся с проблемой, когда iOS выдает моему UITextViewDelegate неверную информацию при удержании клавиши delete на клавиатуре.

Когда пользователь УДЕРЖИВАЕТ клавишу удаления в UITextView на iPad, UITextView начнет удалять целые слова вместо отдельных символов, чем дольше он удерживается нажатым (примечание: в симуляторе этого не происходит).

Когда это происходит, метод делегирования UITextView:

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
  

Вызывается с диапазоном, состоящим из правильного местоположения курсора, но длиной 1. Это неверно, поскольку UITextView теперь удаляет целые слова, а не отдельные буквы. Следующий код, например, напечатает только один пробел.

 [textView substringWithRange:range]
string contains " "
  

Несмотря на то, что UITextView удаляет целое слово. Текст замены правильно задан в виде пустой строки. Кто-нибудь знает о решении или обходном пути этой проблемы?

Комментарии:

1. Есть успехи с этим simeon? Есть ли способ предотвратить действие «удалить по слову» или что-то в этомроде?

2. Я все еще не могу найти способ предотвратить это (или заставить его отправлять правильные данные делегату), но возможность обнаружить это позволила мне обойти ошибку.

3. Обратите внимание, что в UITextViewDelegate есть дополнительная ошибка. Если в настройках вы установите «Общие»-> «Специальные возможности»-> «Тройной щелчок Home» на «VoiceOver» или «Спросить», то UITextViewDelegates получит повторяющиеся сообщения «shouldChangeTextInRange» для любых знаков препинания. Это было чрезвычайно сложно отследить.

4. Зачем использовать оба shouldChange и didChange, если вы только регистрируете изменение?

5. Поскольку shouldChange выдает мне дельта-изменение, которое позволяет быстрее обновлять внутренний буфер. didChange потребовал бы от меня проанализировать текст на предмет различий.

Ответ №1:

Джейкоб упомянул, что я должен опубликовать это в качестве ответа. Итак, вот оно.

Мой хакерский способ решения этой проблемы — отслеживать длину текста и диапазон, указанные в shouldChangeTextInRange, а затем сравнивать их с длиной текста в textViewDidChange. Если различия не синхронизированы, я очищаю свой резервный текстовый буфер и перестраиваю его из текстового представления. Это не оптимально. Вот мой временный обходной путь:

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    //Push the proposed edit to the underlying buffer
    [self.editor.buffer changeTextInRange:range replacementText:text];

    //lastTextLength is an NSUInteger recording the length that
    //this proposed edit SHOULD make the text view have
    lastTextLength = [textView.text length]   ([text length] - range.length);

    return YES;
}

- (void)textViewDidChange:(UITextView *)textView
{
    //Check if the lastTextLength and actual text length went out of sync
    if( lastTextLength != [textView.text length] )
    {
        //Flush your internal buffer
        [self.editor.buffer loadText:textView.text];
    } 
}