it-swarm.dev

Programmgesteuertes Anzeigen der Softtastatur auf dem iPhone in einer PhoneGap-Anwendung?

Ich habe lange gesucht und bis jetzt bin ich nicht auf eine funktionierende Lösung für PhoneGap/Cordova-Anwendungen gestoßen, die programmgesteuert Softkeyboards anzeigen würden.

Szenario:

Wir haben eine PhoneGap-Anwendung - eine in jQuery Mobile erstellte Website -, die dem Benutzer zu einem bestimmten Zeitpunkt einen Dialog anzeigt. Dieser Dialog ist auch eine Webseite und hat ein einziges EINGABE-Textfeld, in das der Benutzer einen Code eingeben sollte.

Problem:

Wenn der Code-Dialog angezeigt wird, ist dasEingabefeld wird mit JavaScript fokussiert. Aufgrund von Einschränkungen im internen Browser des iPhones wird die Soft-Tastatur jedoch erst angezeigt, wenn der Benutzer tatsächlich auf das Eingabetextfeld klickt.

Was wir versucht haben:

  • erstelle einverstecktes Textfeldund mache esErsthelfer
  • den eigentlichenWebview als Ersthelferfestlegen, sobald die Eingabe über JavaScript den Fokus erhält
  • verwenden vonsendActionsForControlEvents, um Touch-Ereignisse in der Webansicht anzuzeigen (auch wenn jeder einen Arbeitscode für eine PhoneGap-Anwendung hat, würde ich es begrüßen, wenn er ihn freigeben könnte, da ich keine bin professionell in der iOS-Codierung)

Irgendwelche Ideen?


BEARBEITEN: Die in dieser Frage erwähnte Einschränkung gilt nur füreingebaute Browser... wenn Sie auf Opera abzielen, werden Sie erfolgreich sein, wenn Sie das verwenden folgenden Code:

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

EDIT2: Dies ist ein endgültiger funktionierender PhoneGap-Code, der in einem Plugin verwendet werden kann:

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

Sie können die Koordinaten für das Eingabefeld mithilfe von Javascript im WebView abrufen. Platzieren Sie dann Ihr eigenes textField direkt darauf und senden Sie in der Delegat-Methode textFieldShouldReturn eine Anforderung mit dem vom Benutzer eingegebenen Code an den Server.

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

Dann implementieren Sie textFieldShouldReturn und erstellen Ihre Anfrage an den Server dort. 

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

Dies geschieht in einem vorhandenen Projekt, jedoch ohne PhoneGap. Ich hoffe, Sie können es an Ihre Bedürfnisse anpassen.

Um das Textfeld zu entfernen, können Sie es ausblenden

myTextField.hidden = YES;

oder

myTextField = nil;

oder

[myTextField removeFromSuperView];
7
Andrei Filip

Sie können das Problem in diesen Tagen mit einem config.xml-Eintrag lösen.

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

Vor iOS 6 erlaubte Apple nur, die Tastatur nach einer Benutzerinteraktion aufzurufen. In iOS 6 wurde die folgende Eigenschaft für UIWebView eingeführt, die Sie lediglich auf NO setzen müssen.

    "yourWebView".keyboardDisplayRequiresUserAction = NO;

Apple setzt dies standardmäßig auf "Ja". Jetzt können Sie focus() in Ihrem JS aufrufen und die Tastatur wird angezeigt. 

5
Karoh

Haben Sie versucht, native Steuerelemente zu verwenden und sie über Javascript aufzurufen?

Hier finden Sie Code, der die Verwendung von systemeigenen Steuerelementen in einer Phonegap Cordova-Anwendung (Phonegap 1.5) veranschaulicht.

https://Gist.github.com/1384250

Hoffe es hilft das Problem zu lösen :)

3
axierjhtjz

Ich habe gerade eineLösung gefunden . Wie horak sagt und wie in diesem Artikel beschrieben , mit oder ohne Soft-Tastatur, ist es jetzt möglich, dies mit iOS 6.0 durch zu erreichen using: KeyboardDisplayRequiresUserAction = NO;

Ab Cordova 2.2 kann die oben erwähnte iOS-Eigenschaft einfach zur Datei Cordova.plist hinzugefügt werden:

KeyboardDisplayRequiresUserAction, boolean, NO

Dies löst alles für jeden, der Cordova 2.2 verwendet. Rufen Sie einfach input.focus () wie zuvor beschrieben auf, und die Tastatur wird automatisch angezeigt. Für diejenigen von uns, die unser Cordova noch nicht auf die aktuellste Version (2.2) aktualisiert haben, ist es glücklicherweise noch möglich .

Zeigen Sie die Tastatur auf dem iPhone mithilfe von Cordova v. <2.2 programmatisch an

Schritt 1 : Eigenschaft zu Cordova.plist hinzufügen

Gehen Sie zu Ihrem Projekt> Ressourcen> Cordova.plist. Hinzufügen: KeyboardDisplayRequiresUserAction, boolean, NO

Schritt 2 : Hinzufügen des nachstehenden Codeausschnitts zu CDVViewController.m

Search für "@interface CDVViewController" (oder ähnlich, um über der Datei zu suchen). Für Cordova 2.1 gehen Sie zu Zeile 240 (alle anderen gehen nach einer "IsAtLeastiOSVersion" in eine Zeile. Falls die Anweisung, Entschuldigung kann es nicht präziser sein.) Hinzufügen Dieses Code-Snippet zu Ihrem CDVViewController.m in der oben genannten Zeile:

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 : Dies wurde nur mit Cordova 2.1 getestet, es ist jedoch sehr wahrscheinlich, dass es noch mit 2.0 oder einer anderen früheren Version arbeitet, die mit der Datei CDVViewController.m geliefert wird.)

3
Jonathan

Ich gebe zu, dass dies privat ist, aber es könnte Ihnen helfen:

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

Und nenne es so:

showKeyboard();
3
user529758

Sie können das FocusOut-Ereignis für das Eingabefeld verwenden. Dieses Ereignis wird ausgelöst, wenn Sie die Taste Done drücken. Ich könnte dies auf IOS 6 und darüber verwenden. Ich glaube, dass es auch bei früheren Versionen funktionieren wird.

0
Prince Nishchal