[英]Programmatically show soft keyboard on iPhone in a PhoneGap application?
I've been searching far and long, and to this moment, I did not come across a working solution for PhoneGap / Cordova applications that would show soft keyboard programmatically. 我一直在寻找很长很长的时间,到目前为止,我没有遇到过可以通过编程方式显示软键盘的PhoneGap / Cordova应用程序的解决方案。
Scenario: 场景:
We have a PhoneGap application - a website created in jQuery Mobile - that at one point shows a dialog to the user. 我们有一个PhoneGap应用程序 - 一个在jQuery Mobile中创建的网站 - 在某一点上显示了一个用户对话框。 This dialog is also a web page and has one single INPUT text box where user should enter a code.
此对话框也是一个网页,并且只有一个INPUT文本框,用户应在其中输入代码。
Problem: 问题:
When the code dialog is shown, the input box is focused using JavaScript . 显示代码对话框时, 使用JavaScript聚焦输入框 。 However, due to restrictions placed on iPhone's internal browser, the soft keyboard does not come up until the user actually really clicks inside the input text box.
但是,由于iPhone内部浏览器受到限制,在用户实际真正点击输入文本框之前,软键盘才会出现。
What we tried: 我们尝试了什么:
Any ideas? 有任何想法吗?
EDIT: The restriction mentioned in this question is for built-in browsers only... if you're aiming Opera, you will be successful by using the following code: 编辑:此问题中提到的限制仅适用于内置浏览器 ...如果您的目标是Opera,您将通过使用以下代码获得成功:
var e = jQuery.Event("keydown", { keyCode: 37 });
$('#element').focus().trigger(e);
EDIT2: This is a final working PhoneGap code that can be used in a plugin: EDIT2:这是一个可以在插件中使用的最终工作PhoneGap代码:
keyboardhelper.h 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
//
// 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 JavaScript的
var keyboardHelper = {
showKeyboard: function(types, success, fail) {
return Cordova.exec(success, fail, "keyboardHelper", "showKeyboard", types);
}
};
您现在可以使用config.xml
条目解决问题,添加:
<preference name="keyboardDisplayRequiresUserAction" value="false" />
You can get the coordinates for the input field using javascript on the webView. 您可以使用webView上的javascript获取输入字段的坐标。 Then, place your own textField right on top of it and in it's delegate method textFieldShouldReturn send a request to the server with the code the user typed in.
然后,将您自己的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;
Then you implement textFieldShouldReturn and create your request to the server there. 然后实现textFieldShouldReturn并在那里向服务器创建请求。
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
//here you create your request to the server
return NO;
}
This is done in existing project, however without using PhoneGap. 这是在现有项目中完成的,但不使用PhoneGap。 I hope you can adapt it to suit your needs.
我希望你能适应它,以满足你的需求。
To remove the text field, you can hide it 要删除文本字段,可以隐藏它
myTextField.hidden = YES;
or 要么
myTextField = nil;
or 要么
[myTextField removeFromSuperView];
Prior to iOS 6, Apple only allowed the keyboard to be brought up following a user interaction. 在iOS 6之前,Apple只允许在用户交互后调出键盘。 In iOS 6 they've introduced the following property for UIWebView which you merely need to set to NO.
在iOS 6中,他们为UIWebView引入了以下属性,您只需将其设置为NO即可。
"yourWebView".keyboardDisplayRequiresUserAction = NO;
Apple sets this by default to "Yes". Apple默认将此设置为“是”。 Now you can call
focus()
in your JS and the keyboard will appear. 现在你可以在JS中调用
focus()
并显示键盘。
Have you tried using Native Controls and calling them from Javascript? 您是否尝试过使用Native Controls并从Javascript中调用它们?
Here you have some code that shows the usage of Native Controls on a Phonegap Cordova application (Phonegap 1.5) 这里有一些代码,显示Phonegap Cordova应用程序上的Native Controls的使用情况(Phonegap 1.5)
https://gist.github.com/1384250 https://gist.github.com/1384250
Hope it helps to solve the problem :) 希望它有助于解决问题:)
I admit this is private, but it might help you out: 我承认这是私人的,但它可能会帮助你:
@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];
}
}
And call it like this: 并称之为:
showKeyboard();
I actually just found a solution to this . 我实际上刚刚找到了解决方案 。 Like horak says and as described in this article , with or without soft keyboard, it's now possible to achieve this with iOS 6.0 by using: KeyboardDisplayRequiresUserAction = NO;
像霍拉克说和这篇文章中描述 ,有或没有软键盘,它现在可以与iOS 6.0通过实现这一点:KeyboardDisplayRequiresUserAction = NO;
As of Cordova 2.2, the iOS property mentioned above can simply be added to the Cordova.plist file: 从Cordova 2.2开始,上面提到的iOS属性可以简单地添加到Cordova.plist文件中:
KeyboardDisplayRequiresUserAction, boolean, NO
This solves it all for everyone using Cordova 2.2. 这解决了所有使用Cordova 2.2的人。 Now just call input.focus() as previously discussed, and the keyboard will automatically appear.
现在只需调用input.focus() ,如前所述,键盘将自动出现。 For those of us who haven't yet updated our Cordova to the current latest version (2.2), it's fortunately still possible .
对于我们这些尚未将Cordova更新到当前最新版本(2.2)的人来说,幸运的是仍然可行 。
Step 1 : Adding property to Cordova.plist 第1步 : 向Cordova.plist添加属性
Go to your project > Resources > Cordova.plist. 转到您的项目> Resources> Cordova.plist。 Add: KeyboardDisplayRequiresUserAction, boolean, NO
添加:KeyboardDisplayRequiresUserAction,boolean,NO
Step 2 : Adding below code snippet to CDVViewController.m 第2步 : 将下面的代码片段添加到CDVViewController.m
Search for "@interface CDVViewController" (or similar to locate above file). 搜索 “@interface CDVViewController”(或类似于找到上面的文件)。 For Cordova 2.1, go to line 240 (everyone else go to a line after a " IsAtLeastiOSVersion " if statement, sorry can't be more precise than that.) Add this code snippet to your CDVViewController.m on the above mentioned line:
对于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"];
}
}
Disclaimer : This has been tested on Cordova 2.1 only, it is, however, very likely that it still works with 2.0 or any other earlier version that comes with the CDVViewController.m file) 免责声明 : 这仅在Cordova 2.1上进行了测试,但它很可能仍然适用于2.0或CDVViewController.m文件附带的任何其他早期版本)
You can use the FocusOut event on the input field and this will be fired when the Done key is pressed. 您可以在输入字段上使用FocusOut事件,并在按下完成键时触发此事件。 I could use this on IOS 6 and above.
我可以在IOS 6及更高版本上使用它。 I believe it will also work on previous versions.
我相信它也适用于以前的版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.