UITextView плавающий синий прямоугольник при прокрутке
У меня UITextView с отключенной прокруткой. Это внутри UIScrollView. Если я наберу "fffs", появится * маленькая синяя рамка. Если я прокручиваю, пока отображается это окно, оно не исчезает, оно просто ** плавает по экрану и выглядит как очевидная ошибка.
Если я использую UITextView с включенной прокруткой, окно скрывается, как только UITextView начинает прокручиваться. Я предполагаю, что UITextView перехватывает события прокрутки своих собственных полос прокрутки, когда он их имеет, и скрывает это поле при прокрутке. Этого не происходит, когда он находится внутри какого-то другого UIScrollView, поэтому мне, вероятно, нужно сделать это самому, но как мне заставить его скрыть этот блок (и, возможно, все остальное, что обычно делает, например, применить автокоррекцию) - в надежный и не приватный способ API?
Я мог бы подать ошибку в Apple, но в то же время я надеюсь, что у кого-то есть быстрое решение.
* маленькая синяя рамка = автокоррекция / выделение - не знаю точно, как его назвать, возможно, поэтому я не смог найти ни одного существующего ответа.
** плавает = думаю, отображение: исправлено в CSS
Обновить:
Я попробовал это и некоторые другие варианты этого, внутри scrollViewWillBeginDragging:
UITextView *tv = GetFirstResponder(); // confirmed this returns correct value
tv.autocorrectionType = UITextAutocorrectionTypeNo;
[tv setNeedsDisplay];
[tv setNeedsLayout];
[tv setNeedsUpdateConstraints]; // just for giggles?
Я подтвердил, что код работает, и я даже не удосужился добавить код для повторного включения автокоррекции, поэтому я знаю, что он не включается снова. Я также могу подтвердить, что он несколько "работает", потому что когда я щелкаю по другому полю, а затем возвращаюсь к исходному полю, автокоррекция теперь отключена.
Я думаю, если бы я мог найти UIView для этой маленькой синей рамки, я мог бы спрятать / удалить ее. Я попытался использовать новый View Debugging в XCode, но он не захватывает синий прямоугольник, поэтому он должен быть особенным.
При том, что все люди используют UITextView таким же образом, как и я (изменяйте размер при вводе, никакой внутренней прокрутки), я удивлен, что никто еще не понял этого. Если это не новая ошибка, я использую последнюю версию iOS и оба моих тестовых устройства (iPod 5 и iPad).
3 ответа
Кажется, пока это работает, но я еще не провел тонны тестирования:
-(void) walkViews:(UIView*)v
{
NSString *className = NSStringFromClass([v class]);
if([className isEqualToString:@"UIAutocorrectInlinePrompt"])
v.hidden = YES;
NSArray *subviews = v.subviews;
for(UIView *sv in subviews)
[self walkViews:sv];
}
-(void) scrollViewDidScroll:(UIScrollView *)scrollView
{
NSArray *windows = [UIApplication sharedApplication].windows;
for (UIWindow *w in windows)
{
[self walkViews:w];
}
}
Возможно, вы бы хотели получить более подходящее название для "walkViews", но в основном, когда прокручивается UIScrollView, я нахожу представление "маленького синего прямоугольника" и скрываю его. Пока что мое ограниченное тестирование, коробка вернется, если я начну печатать снова, и это необходимо. Похоже, что это не мешает другим функциям автокоррекции. Все еще хак, и с учетом всех проблем, которые идут с этим типом вещи, но пока Apple не сможет исправить эту ошибку, я, вероятно, буду использовать этот обходной путь.
Попробуйте установить его autocorrectionType
в UITextAutocorrectionTypeNo
,
Это похоже на проблему Apple. В качестве обходного пути вы можете автоматически отклонить запрос автокоррекции при запуске прокрутки, как показано ниже.
Примечание 1: Написано на Xamarin, но легко переведено на цель-C.
Примечание 2: метод отклонения запроса автозамены взят здесь.
Примечание 3: вы можете найти метод FindFirstResponder() здесь.
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
scrollView.DraggingStarted += scrollView_DraggingStarted;
}
public override void ViewWillDisappear(bool animated)
{
scrollView.DraggingStarted -= scrollView_DraggingStarted;
base.ViewWillDisappear(animated);
}
void scrollView_DraggingStarted(object sender, EventArgs e)
{
UIView activeView = FindFirstResponder(View);
if (activeView != null)
{
UITextView activeTextView = activeView as UITextView;
if (activeTextView != null)
{
RejectAutocorrectPrompt(activeTextView);
}
}
}
private void RejectAutocorrectPrompt(UITextView textView)
{
string originalText = textView.Text;
NSRange originalRange = textView.SelectedRange;
CGPoint originalOffset = textView.ContentOffset;
//Force any pending autocorrection to be applied
textView.ResignFirstResponder();
textView.BecomeFirstResponder();
string finalText = textView.Text;
if (originalText != finalText)
{
textView.Text = originalText;
textView.SelectedRange = originalRange;
textView.SetContentOffset(originalOffset, false);
}
}