#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];
}
}