UITextView滚动时浮动蓝框

UITextView floating blue box when scrolling

我有一个禁用滚动的 UITextView。它位于 UIScrollView 中。如果我输入 "fffs",会出现一个 * 小蓝框。如果我在显示该框时滚动,该框不会消失,它只是 ** 漂浮在显示屏上,看起来像一个明显的错误。

如果我在启用滚动的情况下使用 UITextView,则该框会在 UITextView 开始滚动时立即隐藏。我假设 UITextView 挂钩它自己的滚动条的滚动事件,当它有它们时,并在它滚动时隐藏那个框。当它在其他一些 UIScrollView 中时不会发生这种情况,所以我可能需要自己做,但是我如何让它隐藏那个框(也许它通常做的任何其他事情,比如应用自动更正)——在一种健壮且非私有的 API 方式?

我可能会向 Apple 提交错误,但与此同时我希望有人能快速修复。

*小蓝框 = 自动更正 box/highlight 东西 -- 不确定确切地称呼它,也许是为什么我找不到任何现有答案。

**浮动 = 认为 display:fixed 在 CSS

更新:

我在 scrollViewWillBeginDragging:

中尝试了这个和这个的一些其他变体
UITextView *tv = GetFirstResponder(); // confirmed this returns correct value
tv.autocorrectionType = UITextAutocorrectionTypeNo;
[tv setNeedsDisplay];
[tv setNeedsLayout];
[tv setNeedsUpdateConstraints]; // just for giggles?

我确认代码是 运行,我什至没有费心添加代码来重新启用自动更正,所以我知道它没有被重新打开。我还可以确认它是 "working",因为当我单击另一个字段,然后返回到原始字段时,自动更正现在被禁用。

我在想,如果我能找到那个小蓝框的 UIView,我就能 hide/remove 了。我在XCode中尝试使用新的View Debugging,但它没有捕获到蓝色框,所以它一定是特殊的。

所有以与我类似的方式使用 UITextView 的人(在您键入时调整大小,没有内部滚动),令我惊讶的是还没有人弄清楚这一点。除非它是一个全新的错误,否则我使用的是最新的 iOS 版本和我的两个测试设备(iPod 5 和 iPad)。

尝试将其 autocorrectionType 设置为 UITextAutocorrectionTypeNo

到目前为止这似乎有效,但我还没有进行大量测试:

-(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 滚动时,我找到 "little blue box" 的视图并将其隐藏。到目前为止,我进行了有限的测试,如果我再次开始输入并且需要它,该框确实会返回。它似乎也没有弄乱任何其他自动更正功能。仍然是 hack,并且会受到此类问题带来的所有问题的影响,但在 Apple 可以修复此错误之前,我可能会使用此解决方法。

这似乎是 Apple issue。作为解决方法,您可以在开始滚动时自动拒绝自动更正提示,如下所示。

注 1:用 Xamarin 编写,但很容易翻译成 objective-C。

注2:拒绝自动更正提示的方法取自here.

注3:可以找到FindFirstResponder()方法here.

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);
    }
}