2017-09-22 116 views
6

后,iOS 11上的Phonegap/Cordova选择显示再次弹出我在iPad上使用iOS 11上的Phonegap时遇到问题。如果单击某个选择,它将在弹出窗口中显示选项。选择一个后,弹出窗口短暂消失,选择中的选项会更改,然后弹出窗口重新出现。以下消息是在Xcode控制台:选择选项

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

编辑:后弹出重新出现,什么时候你点击它发生。

如何在选择选项后选择不重新显示弹出窗口?

这是使用最新的Phonegap 7.0.1。

这只是一个普通的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> 
</head> 
<body> 
<select> 
<option value="1">Option 1</option> 
<option value="2">Option 2</option> 
<option value="3">Option 3</option> 
</select> 
</body> 
</html> 

您可以在这里下载的示例项目:

https://github.com/tomkincaid/selecttest

我通过直接打开平台/ IOS/SelectTest.xcodeproj运行此Xcode中。

编辑:有两个选择,行为更奇怪。

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

点击select1,它弹出带有select1选项的弹出窗口。

选择一个选项,弹出短暂消失,然后重新出现。

点击正文使弹出消失。

单击select2。出现select1弹出窗口。

点击正文使弹出消失。弹出窗口暂时消失,然后重新出现空白。

点击正文使弹出消失。

再次点击select2。现在它显示正确的弹出窗口。

+0

任何解决方法?我在整个应用程序中也面临同样的问题 –

+0

@ Anjana-Systematix正如其他答案中提到的1)用Xcode 8进行编译,但不知道App Store是否会接受这个或2)拦截点击选择并呈现定制选取器。 –

回答

0

看来这是iOS 11上的UIWebVIew针对iPad上的所有应用程序而不仅仅是Phonegap/Cordova的问题。由于UIWebVIew对WKWebView的折旧,Apple不太可能修复它。在Phonegap/Cordova使用WKWebView之前,我一直在修复这个问题。基本上,它把一个div放在select上,然后从一个自定义插件打开一个选择器。

的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

在我的实际生产实施中,这有点复杂。我使用Jquery mobile,它将自己的div中的选择内容封装起来,因此我将这个叠加层放入了封装器中,以便它与选择器一起滚动。我会检查一个选择器是否已经出现,并在显示一个新选取器之前将其删除。到目前为止它工作得很好,我更喜欢iPhone风格的选择器,而不是iPad风格的提示器。 –

+0

你有链接添加插件吗?我们如何获得从下拉列表中选择的选项的回调? – sSD

+0

代码如上。你可以自定义你想要的。点击“完成”按钮即可获得回调。 –

1

你可以尝试建立与释放标志您的应用程序?例如:

cordova build --release ios 

我能够重现问题没有释放标志,但与它,问题消失。因此,我想知道这个问题的真正来源:是否真的在苹果方面?似乎是科尔多瓦方面...或者我错过了一些东西。

一些关于我的environement的信息可能是有用的:

  • 的iOS 11.0.1
  • 科尔多瓦CLI 6.5.0
  • 科尔多瓦-的iOS 4.4.0

编辑:我的坏,它完全与发布版本无关,只是因为我的发布版本是在另一台运行XCode 8的Mac上完成的。实际上,只有当您使用XCode 9构建应用程序时才会出现此问题。构建iOS11应用程序从XCode 8开始工作,所以我的建议是使用XCode 8,直到我们在苹果或科尔多瓦方面有了一个可靠的解决方案。

来源:https://forums.developer.apple.com/thread/88169

+1

感谢您对Xcode 8的建议。这个问题我肯定与Apple有关。我制作了一个由UIWebView组成的测试应用程序,并且发生了相同的问题。 –

+0

任何替代解决方案?请帮助...在整个我的应用程序这个问题出现... –

+0

AFAIK,唯一的替代解决方案是重写选择组件。有两种选择:从本地端(iOS平台的cordova插件 - 上面有@TomKincaid发布的示例)或JS端(AngularJS指令似乎是一个合理的途径,只需谷歌它,你会发现很多例子) –

1

恰好碰到了这个故障。我发现这个插件,可以帮助大家:

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

基本上迫使科尔多瓦使用WKWebView。只是一个免责声明...我没有运行我们的应用程序通过适当的浸泡测试后,使用这个,所以我不知道这是否会导致其他问题,但它确实解决了选择问题。

目前在科尔多瓦v.7.0.1和科尔多瓦iOS平台4.4.0

+0

好吧,经过大量测试后,WKWebview有一些严重的限制。无法在控制台中记录JS错误(只是在第0行发生一般脚本错误,无论发生什么情况)。 WKWebview也不能很好地与dataStorage玩...我似乎无法检索我在本地存储的任何图像,只是给了一个空白。另请参阅localStorage的一些问题。如果你们打算使用这个插件,在发布之前浸泡你的应用程序。我不得不回滚到不使用它。 –