iOS:有时键盘会向上推整个qml页面

iOS:有时键盘会向上推整个qml页面,ios,qt,keyboard,qml,Ios,Qt,Keyboard,Qml,我正在开发一个跨平台的QML QtQuick应用程序。一个窗口是典型的聊天窗口,下面有标题、消息区和文本编辑输入。在iOS上(在模拟器和真实设备中),我遇到了虚拟键盘的问题,它“移动”文本编辑以及整个窗口,并且不允许看到标题 以下是应用程序窗口的屏幕截图: 已经在Qt bug跟踪器中注册了相同的错误。但没有解决办法。此外,论坛上也报道了类似的问题,但没有答案 关于解决方案或变通办法有什么想法吗?我过去实施过变通办法,但确实存在问题 避免键盘是一种痛苦,而Qt的一刀切滚动整个屏幕的方法并不理想(特

我正在开发一个跨平台的QML QtQuick应用程序。一个窗口是典型的聊天窗口,下面有标题、消息区和文本编辑输入。在iOS上(在模拟器和真实设备中),我遇到了虚拟键盘的问题,它“移动”文本编辑以及整个窗口,并且不允许看到标题

以下是应用程序窗口的屏幕截图:

已经在Qt bug跟踪器中注册了相同的错误。但没有解决办法。此外,论坛上也报道了类似的问题,但没有答案


关于解决方案或变通办法有什么想法吗?

我过去实施过变通办法,但确实存在问题

避免键盘是一种痛苦,而Qt的一刀切滚动整个屏幕的方法并不理想(特别是当它有问题且禁用时),导致导航栏离开屏幕,等等

基本上,我的工作是:

  • 添加一个
    MouseArea
    作为
    TextField
    的子项,这将停止设置焦点和启动默认滚动行为
  • 在该
    MouseArea
    onClick
    处理程序中,移动该字段,使其不在键盘显示区域下方。这可以通过使用状态和行为动画来实现
  • 当动画停止时,显式地将焦点设置为文本字段,这将导致键盘弹出(但屏幕不会滚动,因为您已将焦点元素移开)
让这些东西很好地动画化可能是一件痛苦的事情。此外,您可以在某种程度上硬编码键盘的大小,但需要借助ObjC来获得实际的键盘高度(并通过某些属性将其暴露给QML)

另一方面,即键盘解雇,也可能是一种痛苦。需要处理文本字段失去焦点、用户点击空白、用户点击关闭键(在iPad上)等问题


在Qt的辩护中,避免键盘是很难做到的,需要了解应用程序布局才能获得最佳效果。这就是为什么UIKit实际上根本不处理它(除非它可以知道滚动什么和滚动多少,比如表格)。

我在iOS上遇到了类似的QTextEdit问题。当QTextEdit位于虚拟键盘下时,整个窗口向上移动。我查看了qt代码,发现当inputMethodQuery属性qt::ImCursorRectangle返回的值位于虚拟键盘下时,qt会将小部件向上移动。我通过为属性Qt::ImCursorRectangle返回无效的QRectF解决了窗口向上移动的问题

QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
{
    if (property & Qt::ImCursorRectangle) {
        return QVariant(QRectF(0,0, 0, 0));
    } else {
        return QTextEdit::inputMethodQuery(property);
    }
}

根据
user2632422
的答案,我实现了一个处理QML项的变通方法。其思想是在QQuickItem上安装一个事件过滤器,并使用
Qt::InputMethodQuery::ImCursorRectangle
侦听
QEvent::InputMethodQuery
。然后我们将其值设置为空QRectF,Qt将不再滚动视图以显示该文本字段

< P>我假定你知道如何将C++类暴露给QML(如果没有,检查)

在C++中编写一个类并将其公开给QML:

class Api : public QObject {
Q_OBJECT
....
public:
    Q_INVOKABLE void setupImEventFilter(QQuickItem *item) {
        static thread_local ImFixer imf;
        item->installEventFilter(&imf);
    }
}

// somewhere in main(): view.rootContext()->setContextProperty("api", new Api());
我们还需要实际的事件筛选器:

class ImFixer : public QObject {
    Q_OBJECT
protected:
    bool eventFilter(QObject *obj, QEvent *event) override {
        if (event->type() == QEvent::InputMethodQuery) {
            QInputMethodQueryEvent *imEvt = static_cast<QInputMethodQueryEvent *>(event);
            if (imEvt->queries() == Qt::InputMethodQuery::ImCursorRectangle) {
                imEvt->setValue(Qt::InputMethodQuery::ImCursorRectangle, QRectF());
                return true;
            }
        }
        return QObject::eventFilter(obj, event);
    }
};

此问题也在中进行了跟踪,希望它能添加到未来的Qt版本中。

您能提供一些解决方案的代码吗:-)?您能找到此问题的任何示例吗,。。两年后,仍然是同样的问题。如果是,请指导,提前感谢
TextField {
    id: tf;
...
    Component.onCompleted: api.setupImEventFilter(tf);
}