2017-09-22 1 views
6

J'ai un problème en utilisant Phonegap sur iOS 11 sur un iPad. Si vous cliquez sur un bouton, il affiche les options dans une fenêtre contextuelle. Après en avoir sélectionné un, la fenêtre disparaît brièvement, l'option de la sélection change, puis la fenêtre contextuelle réapparaît. Le message suivant est dans la console Xcode:Phonegap/Cordova sur iOS 11 sélectionnez les affichages à nouveau pop-up après avoir sélectionné l'option

[Warning] Application tried to represent an active popover presentation: <UIPopoverPresentationController: 0x100c3e450> 

Edit: après le pop-up reparaît, rien ne se passe lorsque vous cliquez dessus.

Comment puis-je obtenir la sélection pour ne pas afficher de nouveau la fenêtre après avoir sélectionné une option?

Ceci utilise le dernier Phonegap 7.0.1.

Il est juste un html normale sélectionnez:

<!doctype html> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<meta name="viewport" content="width=device-width, initial-scale=1 maximum-scale=1, user-scalable=no" /> 
<meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline' 'unsafe-eval'"> 
<script type="text/javascript" src="cordova.js"></script> 
</head> 
<body> 
<select> 
<option value="1">Option 1</option> 
<option value="2">Option 2</option> 
<option value="3">Option 3</option> 
</select> 
</body> 
</html> 

Vous pouvez télécharger un exemple de projet ici:

https://github.com/tomkincaid/selecttest

Je courais en ouvrant directement les plates-formes/ios/SelectTest.xcodeproj dans Xcode. Edit: avec deux sélections, le comportement est encore plus étrange.

<select id="select1"> 
<option value="1">One</option> 
<option value="2">Two</option> 
<option value="3">Three</option> 
</select> 
<select id="select2"> 
<option value="4">Four</option> 
<option value="5">Five</option> 
<option value="6">Six</option> 
</select> 

Cliquez sur select1, cela affiche le popup avec l'option select1.

Sélectionnez une option, le menu contextuel disparaît brièvement puis réapparaît.

Cliquez sur le corps pour faire disparaître la fenêtre.

Cliquez sur select2. La fenêtre de sélection 1 apparaît.

Cliquez sur le corps pour faire disparaître la fenêtre. Le popup disparaît brièvement, puis réapparaît vide.

Cliquez sur le corps pour faire disparaître la fenêtre.

Cliquez à nouveau sur select2. Maintenant, il affiche le bon popup.

+0

Une solution de contournement? Je suis également confronté au même problème tout au long de l'application –

+0

@ Anjana-Systematix Comme mentionné dans les autres réponses 1) compiler avec Xcode 8, mais pas sûr si l'App Store acceptera cela ou 2) intercepter le clic sur le sélectionner et présenter un sélecteur personnalisé. –

Répondre

0

Il semble que ce soit un problème avec UIWebVIew sur iOS 11 pour toutes les applications sur iPad, pas seulement Phonegap/Cordova. Comme UIWebVIew est déprécié pour WKWebView, il est peu probable qu'Apple le corrige. Jusqu'à ce que Phonegap/Cordova utilise WKWebView, j'ai bidouillé ce correctif. Fondamentalement, il met un div sur le select puis ouvre un sélecteur à partir d'un plugin personnalisé.

index.html

<!doctype html> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<meta name="viewport" content="width=device-width, initial-scale=1 maximum-scale=1, user-scalable=no" /> 
<meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline' 'unsafe-eval'"> 
<script type="text/javascript" src="cordova.js"></script> 
<script type="text/javascript" src="jquery.min.js"></script> 
<script type="text/javascript" src="PhonegapUtility.js"></script> 
<script type="text/javascript"> 

function onBodyLoad() { 
    document.addEventListener("deviceready", onDeviceReady, false); 
} 

function onDeviceReady() { 
    addSelectButton('#selecta'); 
    addSelectButton('#selectb'); 
} 

function addSelectButton(selectID) { 
    var u = new PhonegapUtility(); 
    u.isIpad(function(resp){ 
     if (resp == 1) { 
      var buttonID = selectID+"Button"; 
      if($(buttonID).length == 0) { 
       $("body").append("<div id='"+buttonID.replace("#","")+"' onclick='showPicker(\""+selectID+"\");'></div>"); 
      } 
      $(buttonID).css("position","absolute"); 
      $(buttonID).css("left",$(selectID).offset().left+"px"); 
      $(buttonID).css("top",""+$(selectID).offset().top+"px"); 
      $(buttonID).css("width",$(selectID).width()+"px"); 
      $(buttonID).css("height",$(selectID).height()+"px"); 
      // need to adjust this for margin and padding 
     } 
    }); 
} 

function showPicker(selectID) { 
    var optionArray = []; 
    $(selectID).find('option').each(function(index,element){ 
     optionArray.push(element.text); 
    }); 
    var u = new PhonegapUtility(); 
    u.showPicker(optionArray.join("|||"),$(selectID).prop('selectedIndex'),function(resp){ 
     $(selectID+" option")[resp].selected = true; 
    }); 
} 

</script> 
</head> 
<body onload="onBodyLoad();"> 

<select id="selecta"> 
<option value="1">Option 1</option> 
<option value="2">Option 2</option> 
<option value="3">Option 3</option> 
</select> 

<select id="selectb"> 
<option value="4">Option 4</option> 
<option value="5">Option 5</option> 
<option value="6">Option 6</option> 
</select> 

</body> 
</html> 

PhonegapUtility.h

#import <Cordova/CDV.h> 
@interface PhonegapUtility : CDVPlugin <UIPickerViewDelegate,UIPickerViewDataSource> 
@property (strong, nonatomic) NSString *callbackId; 
@property (strong, nonatomic) UIPickerView *pickerView; 
@property (strong, nonatomic) UIView *pickerWrappertView; 
@property (strong, nonatomic) NSArray *pickerData; 
- (void) isIpad:(CDVInvokedUrlCommand*)command; 
- (void) showPicker:(CDVInvokedUrlCommand*)command; 
- (void) pickerDone; 
@end 

PhonegapUtility.m

#import "PhonegapUtility.h" 
#import "AppDelegate.h" 

@implementation TomPhonegapUtility 

@synthesize callbackId,pickerData,pickerView,pickerWrappertView; 

- (void) isIpad:(CDVInvokedUrlCommand*)command { 
    int iPad = 0; 
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) iPad = 1; 
    CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:iPad]; 
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; 
} 

- (void) showPicker:(CDVInvokedUrlCommand*)command { 

    callbackId = [[NSString alloc] initWithString: command.callbackId]; 

    AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate]; 
    UIViewController *rootViewController = appDelegate.window.rootViewController; 

    pickerData = [[command.arguments objectAtIndex:0] componentsSeparatedByString:@"|||"]; 

    float viewWidth = rootViewController.view.bounds.size.width; //[UIScreen mainScreen].bounds.size.width; 
    float viewHeight = rootViewController.view.bounds.size.height; //[UIScreen mainScreen].bounds.size.height; 

    UIToolbar *toolBar= [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, viewWidth, 44)]; 
    [toolBar setBarStyle:UIBarStyleDefault]; 
    UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil]; 
    UIBarButtonItem *barButtonDone = [[UIBarButtonItem alloc] initWithTitle:@"Done" 
                     style:UIBarButtonItemStylePlain 
                    target:self 
                    action:@selector(pickerDone)]; 
    toolBar.items = @[flex, barButtonDone]; 

    pickerView = [[UIPickerView alloc] init]; 
    [pickerView setDataSource: self]; 
    [pickerView setDelegate: self]; 
    [pickerView setFrame: CGRectMake(0, toolBar.frame.size.height, viewWidth, 180.0f)]; 
    pickerView.showsSelectionIndicator = YES; 

    [pickerView selectRow:[[command.arguments objectAtIndex:1] intValue] inComponent:0 animated:NO]; 

    pickerWrappertView = [[UIView alloc] initWithFrame:CGRectMake(0, viewHeight-toolBar.frame.size.height-pickerView.frame.size.height, viewWidth, toolBar.frame.size.height + pickerView.frame.size.height)]; 
    pickerWrappertView.backgroundColor = [UIColor whiteColor]; 
    [pickerWrappertView addSubview:pickerView]; 
    [pickerWrappertView addSubview:toolBar]; 

    [rootViewController.view addSubview:pickerWrappertView]; 
} 

- (void) pickerDone { 
    int selectedIndex = (int) [pickerView selectedRowInComponent:0]; 
    CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:selectedIndex]; 
    [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId]; 
    [pickerWrappertView removeFromSuperview]; 
} 

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{ 
    return 1; 
} 

-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{ 
    return [pickerData count]; 
} 

-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{ 
    return [pickerData objectAtIndex:row]; 
} 

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{ 
} 
+0

Dans mon implémentation de production actuelle, c'est un peu plus compliqué. J'utilise Jquery mobile, qui enveloppe les sélections dans ses propres divs, donc je mets la superposition dans le wrapper pour qu'elle défile avec le select. Je vérifie si un sélecteur est déjà présenté et l'enlève avant de montrer un nouveau sélecteur. Jusqu'à présent, cela fonctionne assez bien et je préfère en fait le sélecteur de style iPhone sur l'alerte de style iPad. –

+0

Avez-vous un lien pour ajouter le plugin? Comment obtenir le rappel de l'option de sélection sélectionnée dans la liste déroulante? – sSD

+0

Le code est au-dessus. Vous pouvez le personnaliser comme vous le souhaitez. Vous obtenez le rappel en cliquant sur le bouton "terminé". –

1

Pouvez-vous essayer de construire votre application avec le drapeau de la libération?Quelque chose comme:

cordova build --release ios 

Je suis en mesure de reproduire le problème sans que le drapeau de la libération, mais avec elle, le problème disparaîtrait. Par conséquent, je m'interroge sur la véritable source de ce problème: est-ce vraiment du côté d'Apple? Semble être du côté de Cordova ... ou peut-être qu'il me manque quelque chose.

Quelques informations sur mon environement peut être utile:

  • iOS 11.0.1
  • Cordova CLI 6.5.0
  • Cordova iOS 4.4.0

EDIT: mon mauvais , ce n'est pas du tout lié à la version release, c'est seulement parce que ma version release est faite sur un autre Mac, fonctionnant sur XCode 8. En effet, le problème n'apparait que lorsque vous construisez l'application avec XCode 9. Création d'application pour iOS11 de XCode 8 fonctionne, donc ma suggestion est d'utiliser XCode 8 jusqu'à ce que nous ayons une solution de contournement solide sur le côté Apple ou Cordova.

Source: https://forums.developer.apple.com/thread/88169

+1

Merci pour les conseils au sujet de Xcode 8. Le problème que j'ai définitivement avec Apple. J'ai fait une application de test qui consistait simplement en un UIWebView et le même problème s'est produit. –

+0

Toute autre solution? S'il vous plaît aidez-moi ... comme dans toute mon application ce problème apparaît ... –

+0

AFAIK, la seule solution alternative est de réécrire le composant select. Deux choix: du côté natif (plugin cordova pour la plate-forme iOS - il y a un exemple posté ci-dessus par @TomKincaid) ou du côté JS (la directive AngularJS semble être une façon raisonnable d'y aller, il suffit de google et vous trouverez de nombreux exemples –

1

Je viens de croiser ce petit problème. J'ai trouvé ce plug-in qui peut aider tout le monde:

https://github.com/apache/cordova-plugin-wkwebview-engine

oblige Fondamentalement Cordova à utiliser WKWebView. Juste un avertissement ... Je n'ai pas exécuté notre application à travers un test de trempage après l'avoir utilisé, donc je ne sais pas si cela va causer d'autres problèmes, mais cela corrige le problème de sélection.

Actuellement sur Cordova v.7.0.1 et la plate-forme Cordova iOS 4.4.0

+0

Ok, donc après une tonne de tests, il y a quelques limitations GRAVES avec WKWebview. Impossible de consigner les erreurs JS dans la console (donne une erreur de script générale à la ligne 0 quoi qu'il arrive). WKWebview ne joue pas aussi bien avec dataStorage ... Je n'arrive pas à récupérer les images que je stocke localement, donne juste un blanc. Voir aussi quelques problèmes avec localStorage. Si vous avez l'intention d'utiliser ce plugin, faites le test de votre application avant de la relâcher. J'ai dû revenir à ne pas l'utiliser. –