控制iPhone上自动更正视图的位置

13

有没有一种方法可以控制在UITextField中输入时弹出的自动纠正视图的位置?

默认情况下,它似乎总是出现在文本框下方。但是在苹果的应用程序(如短信)中,它有时会出现在文本框上方。

对于位于键盘正上方的文本字段,自动更正被键盘挡住,无法使用。


提升一下!1年后还有回答吗? - Chintan Patel
技术上不可能,并且没有公共API可以允许这样做。但是,可以修改纠正弹出窗口的位置:弹出窗口是文本区域的子视图,因此可以通过迭代子视图找到它。然后可以找到它的原始位置并将其移动到任何位置。将此逻辑放入一个方法中,并在每次调用文本字段的“layoutSubviews”时调用它...我还没有看到更清晰的解决方案。 - Nick
4个回答

1

自动更正提示的位置是由UITextInput协议的firstRect...方法确定的。不幸的是,UITextField使用一个私有类作为该协议的代理,因此您无法子类化和覆盖它。

但是,您可以通过自己绘制内容(如使用CoreText),实现自己的选择和放大镜处理,然后您就可以影响自动更正提示的位置。虽然它被设计为始终位于编辑文本下方,因此您必须在firstRect...方法上基本上撒谎。

长话短说:这太麻烦了。


0

这里是一个使用私有API的解决方案,因为没有公共API可以完成这个任务。

  • 搜索应用程序的 -windows 属性来查找私有的 UITextEffectsWindow 窗口,并找出其框架。这就是键盘。
  • 搜索 TextView 的子视图以查找私有的 UIAutocorrectInlinePrompt 视图。这是自动更正气泡。
  • 将该子视图移到单独的包装视图中(添加到 TextView 中),然后将该包装视图移动到上述键盘窗口之上。

使用交换过的 layoutSubViews 函数,

- (void) moveSpellingCorrection {
for (UIView *view in self.subviews)
{
    if ([[[view class] description] isEqualToString:@"UIAutocorrectInlinePrompt"])
    {
        UIView *correctionShadowView = nil; // [view correctionShadowView];

        for (UIView *subview in view.subviews)
        {
            if ([[[subview class] description] isEqualToString:@"UIAutocorrectShadowView"])
            {
                correctionShadowView = subview;
                break;
            }
        }

        if (correctionShadowView)
        {
            UIView *typedTextView = nil; //[view typedTextView];
            UIView *correctionView = nil; //[view correctionView];

            for (UIView *subview in view.subviews)
            {
                if ([[[subview class] description] isEqualToString:@"UIAutocorrectTextView"])
                {
                    if (CGRectContainsRect(correctionShadowView.frame,subview.frame))
                    {
                        correctionView = subview;
                    }
                    else
                    {
                        typedTextView = subview;
                    }
                }

            }
            if (correctionView && typedTextView)
            {

                CGRect textRect = [typedTextView frame];
                CGRect correctionRect = [correctionView frame];
                if (textRect.origin.y < correctionRect.origin.y)
                {
                    CGAffineTransform moveUp = CGAffineTransformMakeTranslation(0,-50.0);
                    [correctionView setTransform: moveUp];
                    [correctionShadowView setTransform: moveUp];

                    CGRect windowPos = [self convertRect: view.frame toView: nil ];
                    [view removeFromSuperview];
                    [self.window addSubview: view];
                    view.frame = windowPos;
                }

            }
        }

    }

}

}

更多细节请查看


0
一个对我有效的答案是使用textview/textfield的setInputAccessoryView方法。我有一个包含textView的工具栏。如果我将工具栏设置为textfield的inputaccessoryview,并将工具栏的clipsToBounds属性设置为NO,虽然我不知道确切的原因,但气球会出现在键盘上方。

你能想出如何使其显示在正在编辑的字段上方而不是下方吗?谢谢! - Jorge Leandro Perez

0
在我的情况下,由于字体的行间距,自动更正视图的位置发生了偏移。
因此,我尝试使用firstRect函数将其上移leading像素,代码如下。
class CustomTextView: UITextView {
    override var font: UIFont? {
        didSet {
            if let font = font {
                leadingFont = font.leading
            } else {
                leadingFont = 0
            }
        }
    }
    var leadingFont: CGFloat = 0

    override func firstRect(for range: UITextRange) -> CGRect {
        var newRect = super.firstRect(for: range)
        newRect.origin = CGPoint(x: newRect.origin.x, y: newRect.origin.y - leadingFont)
        print("newRect: \(newRect)")
        return newRect
    }
}

虽然这是UITextView,但你也可以用UITextField做同样的事情


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接