在PhoneGap应用程序中以编程方式在iPhone上显示软键盘?

时间:2012-08-27 10:44:34

标签: iphone cordova iphone-softkeyboard

我一直在寻找很长很长的时间,到目前为止,我没有遇到过能够以编程方式显示软键盘的PhoneGap / Cordova应用程序的工作解决方案

情境:

我们有一个PhoneGap应用程序 - 一个在jQuery Mobile中创建的网站 - 在某一点上显示了一个用户对话框。此对话框也是一个网页,并且有一个单独的输入文本框,用户应在其中输入代码。

问题:

显示代码对话框时, 输入框将使用JavaScript 进行聚焦。但是,由于iPhone内部浏览器受到限制,在用户实际真正点击输入文本框之前,软键盘才会出现。

我们尝试了什么:

  • 创建 hidden text box 并将其设为 第一响应者
  • 在输入通过JavaScript获得焦点后,使实际的 webview成为第一响应者
  • 使用 sendActionsForControlEvents 尝试将触摸事件传递到webview(虽然如果有人有PhoneGap应用程序的工作代码,我会很感激,如果他们可以共享它,因为我不喜欢iOS编码)

有什么想法吗?


编辑:此问题中提到的限制仅适用于 内置浏览器 ...如果您的目标是Opera,那么将使用以下代码成功:

var e = jQuery.Event("keydown", { keyCode: 37 });
$('#element').focus().trigger(e);

EDIT2:这是一个可以在插件中使用的最终工作PhoneGap代码:

keyboardhelper.h

//
//  keyboardHelper.h
//  soft keyboard displaying plugin for PhoneGap
//
//  Copyright 2012 Martin Ambrus.
//

#import <Foundation/Foundation.h>
#ifdef CORDOVA_FRAMEWORK
#import <Cordova/CDVPlugin.h>
#else
#import "CDVPlugin.h"
#endif

@interface keyboardHelper : CDVPlugin {
    NSString *callbackID;
}

@property (nonatomic, copy) NSString *callbackID;

- (void)showKeyboard:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;

@end

keyboardhelper.m

//
//  keyboardHelper.m
//  soft keyboard displaying plugin for PhoneGap
//
//  Copyright 2012 Martin Ambrus.
//

#import "keyboardHelper.h"
#import "AppDelegate.h"

@implementation keyboardHelper
@synthesize callbackID;

-(void)showKeyboard:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options {
    self.callbackID = [arguments pop];

    //Get text field coordinate from webview. - You should do this after the webview gets loaded
    //myCustomDiv is a div in the html that contains the textField.
    int textFieldContainerHeightOutput = [[((AppDelegate *)[[UIApplication sharedApplication] delegate]).viewController.webView stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"myCustomDiv\").offsetHeight;"] intValue];

    int textFieldContainerWidthOutput = [[((AppDelegate *)[[UIApplication sharedApplication] delegate]).viewController.webView  stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"myCustomDiv\").offsetWidth;"] intValue];

    int textFieldContainerYOffset = [[((AppDelegate *)[[UIApplication sharedApplication] delegate]).viewController.webView  stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"myCustomDiv\").offsetTop;"] intValue];

    int textFieldContainerXOffset = [[((AppDelegate *)[[UIApplication sharedApplication] delegate]).viewController.webView  stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"myCustomDiv\").offsetLeft;"] intValue];

    UITextField *myTextField = [[UITextField alloc] initWithFrame: CGRectMake(textFieldContainerXOffset, textFieldContainerYOffset, textFieldContainerWidthOutput, textFieldContainerHeightOutput)];

    [((AppDelegate *)[[UIApplication sharedApplication] delegate]).viewController.webView addSubview:myTextField];
    myTextField.delegate = self;

    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: @"ok"];

    [self writeJavascript:[pluginResult toSuccessCallbackString:self.callbackID]];
}

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
//here you create your request to the server
return NO;
}

-(BOOL)textFieldDidEndEditing:(UITextField *)textField
{
//here you create your request to the server
return NO;
}

@end

的javascript

var keyboardHelper = {
    showKeyboard: function(types, success, fail) {
        return Cordova.exec(success, fail, "keyboardHelper", "showKeyboard", types);
    }
};

7 个答案:

答案 0 :(得分:12)

您现在可以使用config.xml条目解决问题,添加:

<preference name="keyboardDisplayRequiresUserAction" value="false" />

答案 1 :(得分:7)

您可以使用webView上的javascript获取输入字段的坐标。然后,将您自己的textField放在它的顶部,并在其委托方法textFieldShouldReturn中使用用户输入的代码向服务器发送请求。

    //Get text field coordinate from webview. - You should do this after the webview gets loaded
    //myCustomDiv is a div in the html that contains the textField.
int textFieldContainerHeightOutput = [[webView stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"myCustomDiv\").offsetHeight;"] intValue];

int textFieldContainerWidthOutput = [[webView stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"myCustomDiv\").offsetWidth;"] intValue];

int textFieldContainerYOffset = [[webView stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"myCustomDiv\").offsetTop;"] intValue];

int textFieldContainerXOffset = [[webView stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"myCustomDiv\").offsetLeft;"] intValue];

myTextField.frame = CGRectMake(textFieldContainerXOffset, textFieldContainerYOffset, textFieldContainerWidthOutput, textFieldContainerHeightOutput);
[webView addSubview:myTextField];
myTextField.delegate = self;

然后实现textFieldShouldReturn并在那里向服务器创建请求。

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
//here you create your request to the server
return NO;
}

这是在现有项目中完成的,但不使用PhoneGap。我希望你能根据自己的需要进行调整。

要删除文本字段,可以将其隐藏

myTextField.hidden = YES;

myTextField = nil;

[myTextField removeFromSuperView];

答案 2 :(得分:5)

在iOS 6之前,Apple只允许在用户交互后调出键盘。在iOS 6中,他们为UIWebView引入了以下属性,您只需将其设置为NO。

    "yourWebView".keyboardDisplayRequiresUserAction = NO;

Apple默认将此设置为“是”。现在,您可以在JS中调用focus(),键盘将会出现。

答案 3 :(得分:3)

您是否尝试过使用Native Controls并从Javascript中调用它们?

这里有一些代码显示Phonegap Cordova应用程序中的Native Controls的使用情况(Phonegap 1.5)

https://gist.github.com/1384250

希望有助于解决问题:)

答案 4 :(得分:3)

我承认这是私密的,但它可能会帮助你:

@class UIKeyboard;

void showKeyboard()
{
    static UIKeyboard *kb = nil;
    if ([[UIKeyboard class] respondsToSelector:@selector(automaticKeyboard)])
        kb = [UIKeyboard automaticKeyboard];
    else
        kb = [UIKeyboard activeKeyboard];

    if (kb == nil) {
        kb = [[[UIKeyboard alloc] initWithDefaultSize] autorelease];
        [[[UIApplication sharedApplication] keyWindow] addSubview:kb];
    }

    if ([kb respondsToSelector:@selector(orderInWithAnimation:)]) {
        [kb orderInWithAnimation:YES];
    } else {
        [kb activate];
        [kb minimize];
        [kb maximize];
    }
}

并称之为:

showKeyboard();

答案 5 :(得分:3)

我实际上刚刚找到解决方案。 就像horak所说和described in this article一样,无论有没有软键盘,现在可以使用iOS 6.0实现这一点: KeyboardDisplayRequiresUserAction = NO;

从Cordova 2.2开始,上面提到的iOS属性可以简单地添加到 Cordova.plist 文件中:

KeyboardDisplayRequiresUserAction, boolean, NO

这解决了所有使用Cordova 2.2的人。现在只需按前面所述调用 input.focus(),键盘将自动出现。对于我们这些尚未将Cordova更新到当前最新版本(2.2)的人来说,幸运的是仍然可能

使用cordova v以编程方式在iPhone上显示键盘。 2.2

第1步向Cordova.plist添加属性

转到您的项目&gt;资源&gt; Cordova.plist。添加:KeyboardDisplayRequiresUserAction,boolean,NO

第2步将以下代码段添加到CDVViewController.m

搜索以获取“@interface CDVViewController”(或类似于找到上面的文件)。对于Cordova 2.1,请转到第240行(其他人在“ IsAtLeastiOSVersion ”if语句后转到一行,抱歉不能比这更准确。)将此代码段添加到上面提到的行上的CDVViewController.m中:

if (IsAtLeastiOSVersion(@"6.0")) {
    BOOL keyboardDisplayRequiresUserAction = YES; // KeyboardDisplayRequiresUserAction - defaults to YES
    if ([self.settings objectForKey:@"KeyboardDisplayRequiresUserAction"] != nil) {
        if ([self.settings objectForKey:@"KeyboardDisplayRequiresUserAction"]) {
            keyboardDisplayRequiresUserAction = [(NSNumber*)[self.settings objectForKey:@"KeyboardDisplayRequiresUserAction"] boolValue]; //JB-VAL121212
        }
    }

    // property check for compiling under iOS < 6
    if ([self.webView respondsToSelector:@selector(setKeyboardDisplayRequiresUserAction:)]) {
        [self.webView setValue:[NSNumber numberWithBool:keyboardDisplayRequiresUserAction] forKey:@"keyboardDisplayRequiresUserAction"];
    }

}

免责声明这仅在Cordova 2.1上进行了测试,但它很可能仍然适用于2.0或CDVViewController.m文件附带的任何其他早期版本)

答案 6 :(得分:0)

您可以在输入字段上使用FocusOut事件,并在按下完成键时触发此事件。我可以在IOS 6及更高版本上使用它。我相信它也适用于以前的版本。