容器中的TextField - 键盘隐藏文本 [英] TextField in a Container - Keyboard hides Text

查看:120
本文介绍了容器中的TextField - 键盘隐藏文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在底部的容器(VBox)中有一个TextField。当我选择TextField输入一些文本时,它会隐藏在键盘(iPhone)后面。我把VBox放在ScrollPane中,但仍然是一样的。



我能以某种方式获得键盘以获得它的高度吗?如何放置未被键盘覆盖的TextFields?



感谢您的帮助。

解决方案

目前,JavaFX或JavaFXPorts中没有内置方法来获取(本机)iOS软键盘。



解决方案要获得键盘并找出是否有任何节点,如 TextField ,它将需要服务来自Gluon Charm Down )。它基于 ios-build.gradle file

 任务xcodebuild {
doLast {
xcodebuildIOS($ project.buildDir,$ project.projectDir ,键盘)
}
}

保存项目,然后运行从项目根目录下的命令行 ./ gradlew clean build xcodebuild



如果一切就绪,你应该找到 libKeyboard.a build / native 下。复制文件,在 src / ios 下创建文件夹 jniLibs ,并将其粘贴到那里。




  1. 实施服务

添加 TextField BasicView ,并将对齐方式更改为 BOTTOM-CENTER

  VBox controls = new VBox(15.0,label,button,new TextField()); 
controls.setAlignment(Pos.BOTTOM_CENTER);

实施服务:

  Services.get(KeyboardService.class).ifPresent(keyboard  - > {
keyboard.visibleHeightProperty()。addListener((obs,ov,nv) - >
setTranslateY (-nv.doubleValue()));
});




  1. 部署并运行

你应该拥有一切。插上iPhone / iPad,然后运行 ./ gradlew --info launchIOSDevice



当textField获得焦点时,软键盘显示,视图被翻译,因此textField完全可见:





希望此服务在某些时候会包含在Charm Down中。但这也是如何添加自定义服务的一个很好的例子。还要注意Charm Down项目是开源的,所以任何贡献都是好的。


I have a TextField in a container (VBox) in the bottom. When i select the TextField to enter some text it gets hidden behind the keyboard (iPhone). I put the VBox in ScrollPane but still the same.

Can i get the keyboard somehow to get its height? How do i place TextFields which are not covered from keyboard?

Thank you for your help.

解决方案

At this moment, there is no built-in method in JavaFX or JavaFXPorts to get the (native) iOS soft keyboard.

The solution to get the keyboard and find out if any node, like a TextField will be covered by it, would require a Service from those available in the Gluon Charm Down library, but for now there is no such KeyboardService.

Based on native solutions like this, it's easy to get a notification when the keyboard is being shown or hidden. So we could make use of those listeners and send the height value back to the JavaFX layer.

So let's create the KeyboardService taking into account how the services are created in the Charm Down library.

Since this is a little bit out of scope here, I've created this gist with the required files.

Follow these steps to make it work:

  1. Create a Gluon Project

Create a Gluon project (single view) with the latest version of the Gluon plugin for your IDE.

  1. Add the KeyboardService interface

Add the package com.gluonhq.charm.down.plugins. Add the classes KeyboardService (link) and KeyboardServiceFactory (link).

public interface KeyboardService {
    public ReadOnlyFloatProperty visibleHeightProperty();
}

  1. iOS implementation

Under the iOS package add the iOS implementation of the service IOSKeyboardService (link).

public class IOSKeyboardService implements KeyboardService {

    static {
        System.loadLibrary("Keyboard");
        initKeyboard();
    }

    private static ReadOnlyFloatWrapper height = new ReadOnlyFloatWrapper();

    @Override
    public ReadOnlyFloatProperty visibleHeightProperty() {
        return height.getReadOnlyProperty();
    }

    // native
    private static native void initKeyboard();

    private void notifyKeyboard(float height) {
        Platform.runLater(() -> this.height.setValue(height));
    }

}

  1. Native code

Create a native folder under /src/ios and add the Keyboard.h (link) file:

#import <UIKit/UIKit.h>
#include "jni.h"

@interface Keyboard : UIViewController {}
@end

void sendKeyboard();

and the Keyboard.m (link) file:

static int KeyboardInited = 0;
jclass mat_jKeyboardServiceClass;
jmethodID mat_jKeyboardService_notifyKeyboard = 0;
Keyboard *_keyboard;
CGFloat currentKeyboardHeight = 0.0f;

JNIEXPORT void JNICALL Java_com_gluonhq_charm_down_plugins_ios_IOSKeyboardService_initKeyboard
(JNIEnv *env, jclass jClass)
{
    if (KeyboardInited)
    {
        return;
    }
    KeyboardInited = 1;

    mat_jKeyboardServiceClass = (*env)->NewGlobalRef(env, (*env)->FindClass(env, "com/gluonhq/charm/down/plugins/ios/IOSKeyboardService"));
    mat_jKeyboardService_notifyKeyboard = (*env)->GetMethodID(env, mat_jKeyboardServiceClass, "notifyKeyboard", "(F)V");
    GLASS_CHECK_EXCEPTION(env);

    _keyboard = [[Keyboard alloc] init];
}

void sendKeyboard() {
    GET_MAIN_JENV;
    (*env)->CallVoidMethod(env, mat_jKeyboardServiceClass, mat_jKeyboardService_notifyKeyboard, currentKeyboardHeight);
}

@implementation Keyboard 

- (void) startObserver 
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void) stopObserver 
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

- (void)keyboardWillShow:(NSNotification*)notification {
    NSDictionary *info = [notification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    currentKeyboardHeight = kbSize.height;
    sendKeyboard();
}

- (void)keyboardWillHide:(NSNotification*)notification {
    currentKeyboardHeight = 0.0f;
    sendKeyboard();
}

@end

  1. Build the native library

On a Mac with a recent version of XCode, you can build the native library libKeyboard.a. For that you need to add the xcodebuild task to the build.gradle file of the project (link). It is based on the ios-build.gradle file from Charm Down.

task xcodebuild {
    doLast {
        xcodebuildIOS("$project.buildDir","$project.projectDir", "Keyboard")
    }
}

Save your project, and run ./gradlew clean build xcodebuild from command line under the project root.

If everything is in place you should find libKeyboard.a under build/native. Copy the file, create the folder jniLibs under src/ios, and paste it there.

  1. Implement the service

Add a TextField to the BasicView, and change the alignment to BOTTOM-CENTER.

VBox controls = new VBox(15.0, label, button, new TextField());
controls.setAlignment(Pos.BOTTOM_CENTER);

Implement the service:

Services.get(KeyboardService.class).ifPresent(keyboard -> {
    keyboard.visibleHeightProperty().addListener((obs, ov, nv) -> 
        setTranslateY(-nv.doubleValue()));
});

  1. Deploy and run

You should have everything in place. Plug your iPhone/iPad, and run ./gradlew --info launchIOSDevice.

When the textField gets the focus, the soft keyboard shows up, and the view is translated, so the textField is fully visible:

Hopefully this service will be included in Charm Down at some point. But this is also a good example of how you can add custom services. Also note the Charm Down project is open source, so any contribution is wellcome.

这篇关于容器中的TextField - 键盘隐藏文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆