web-dev-qa-db-fra.com

Afficher par programme le clavier virtuel sur iPhone dans une application PhoneGap?

Je cherche depuis longtemps et, à ce jour, je n’ai pas trouvé de solution de travailpour les applications PhoneGap/Cordova permettant d’afficher le clavier logiciel par programme.

Scénario:

Nous avons une application PhoneGap - un site Web créé dans jQuery Mobile - qui affiche un dialogue à un moment donné à l'utilisateur. Cette boîte de dialogue est également une page Web et contient une seule zone de texte INPUT où l’utilisateur doit entrer un code.

Problème:

Lorsque la boîte de dialogue du code est affichée, la zone ) est sélectionnée à l'aide de JavaScript. Toutefois, en raison de restrictions imposées sur le navigateur interne de l'iPhone, le clavier logiciel n'apparaît que lorsque l'utilisateur clique réellement à l'intérieur de l'entrée. zone de texte.

Ce que nous avons essayé:

  • créer une zone de texte masquéeet la rendre premier répondant
  • faire de la webview) la première réponseune fois que l'entrée reçoit le focus via JavaScript
  • en utilisant _/sendActionsForControlEventspour essayer de fournir des événements Touch à la vue Web (bien que, si quelqu'un a un code fonctionnel pour une application PhoneGap, j'apprécierais de le partager, car je ne suis pas un professionnel du codage iOS. )

Des idées?


EDIT:La restriction mentionnée dans cette question concerne les navigateurs intégrésuniquement ... si vous visez Opera, vous réussirez en utilisant le code suivant:

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

EDIT2:Ceci est un code PhoneGap fonctionnel qui peut être utilisé dans un plugin:

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);
    }
};
27
Zathrus Writer

Vous pouvez obtenir les coordonnées du champ de saisie à l'aide de javascript sur WebView. Ensuite, placez votre propre textField au-dessus de celui-ci et, dans sa méthode de délégation, textFieldShouldReturn, envoyez une demande au serveur avec le code saisi par l'utilisateur.

    //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;

Ensuite, vous implémentez textFieldShouldReturn et créez votre demande sur le serveur. 

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

Ceci est fait dans le projet existant, cependant sans utiliser PhoneGap. J'espère que vous pourrez l'adapter à vos besoins.

Pour supprimer le champ de texte, vous pouvez le masquer.

myTextField.hidden = YES;

ou

myTextField = nil;

ou

[myTextField removeFromSuperView];
7
Andrei Filip

Vous pouvez résoudre le problème avec une entrée config.xml ces jours-ci, ajoutez:

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

Avant iOS 6, Apple autorisait uniquement l'utilisation du clavier à la suite d'une interaction de l'utilisateur. Dans iOS 6, ils ont introduit la propriété suivante pour UIWebView que vous devez simplement définir sur NO.

    "yourWebView".keyboardDisplayRequiresUserAction = NO;

Apple définit ceci par défaut sur "Oui". Vous pouvez maintenant appeler focus() dans votre JS et le clavier apparaîtra. 

5
Karoh

Avez-vous essayé d'utiliser Native Controls et les appeler à partir de Javascript?

Vous avez ici un code qui montre l'utilisation des contrôles natifs sur une application Phonegap Cordova (Phonegap 1.5)

https://Gist.github.com/1384250

J'espère que ça aide à résoudre le problème :)

3
axierjhtjz

En fait, je viens juste de trouver une solution à ce problème . Comme Horak le dit et comme décrit dans cet article , avec ou sans clavier logiciel, il est maintenant possible d'y parvenir avec iOS 6.0 en utilisant: KeyboardDisplayRequiresUserAction = NO;

A partir de Cordova 2.2, la propriété iOS mentionnée ci-dessus peut simplement être ajoutée au fichier Cordova.plist:

KeyboardDisplayRequiresUserAction, boolean, NO

Cela résout tout pour tous ceux qui utilisent Cordova 2.2. Appelez maintenant input.focus () comme indiqué précédemment et le clavier apparaîtra automatiquement. Pour ceux d'entre nous qui n'ont pas encore mis à jour notre Cordova à la dernière version (2.2), c'est heureusement encore possible.

Afficher le clavier par programme sur iPhone avec Cordova v. <2.2

Étape 1: Ajout de la propriété à Cordova.plist

Accédez à votre projet> Ressources> Cordova.plist. Ajouter: KeyboardDisplayRequiresUserAction, boolean, NO

Étape 2: Ajout de l'extrait de code ci-dessous à CDVViewController.m

Recherche pour "@interface CDVViewController" (ou similaire pour localiser le fichier ci-dessus). Pour Cordova 2.1, accédez à line 240 (tout le monde passe à une ligne après une instruction "IsAtLeastiOSVersion", désolé ne peut pas être plus précis que cela.) Ajouter cet extrait de code à votre CDVViewController.m sur la ligne mentionnée ci-dessus:

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: Ceci a été testé sur Cordova 2.1 uniquement. Toutefois, il est fort probable qu'il fonctionne toujours avec la version 2.0 ou toute autre version antérieure fournie avec le fichier CDVViewController.m)

3
Jonathan

J'admets que c'est privé, mais cela pourrait vous aider:

@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];
    }
}

Et appelez ça comme ça:

showKeyboard();
3
user529758

Vous pouvez utiliser l'événement FocusOut sur le champ de saisie et celui-ci sera déclenché lorsque vous appuierez sur la touche Terminé. Je pourrais utiliser ceci sur IOS 6 et les versions ultérieures. Je crois que cela fonctionnera également sur les versions précédentes.

0
Prince Nishchal