2017-09-22 115 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的一些問題。如果你們打算使用這個插件,在發佈之前浸泡你的應用程序。我不得不回滾到不使用它。 –