-
Notifications
You must be signed in to change notification settings - Fork 916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
inconsistent intialization of map on iOS. #623
Comments
Please just try version 1.3.0. Please read the new Readme on the plugins front page (you need to remove google maps sdk before) This has included the new version of iOS sdk. Your problem seem to me more framework independent, like there is a non transparent layer in front |
I am using 1.2.5 and was also facing this problem on iOS (haven't tried with Android). I discovered that the main ion-nav-view (I am using Ionic) inside of my index.html was sometimes not being made transparent - at random. The solution (hack) I found was to give it an ID and flick it's opacity to 0 and then straight away back to 1 inside the "plugin.google.maps.event.MAP_READY event" Really hacky but it at least works every time whereas the map previously often did not appear. @hirbod will try 1.3 soon and see if this is fixed. |
You have to understand that this plugin will only make parent nodes transparent on domready. As soon as the DOM changes (sometimes delayed/ timing issue) the plugin won't be able to make parent nodes transparent. Sometimes (like on onsenui, maybe ionic too), there are elements, which are positioned absolutly and not being registered as a parent node. In this case you will have to do it manually. In my case I have some onsen elements, which I also have to set to background rgba(0,0,0,0) I think version 1.3.0 won't change anything. There is no way around. But I would not wait until map_ready. You should apply your hack as soon as you can consider that all DOM nodes are ready |
Thanks for the explanation @hirbod. Just moved the instruction before I call plugin.google.maps.Map.getMap and it is now better, as there is not any flicker any more, which I had when I waited for the map_ready event. |
Could you show me how you did that @johnrobertcobbold, im using ionic also had have seen this issue and couldn't workout what the problem was. |
@johnrobertcobbold I have seen this problem on 1.2.5, but it appear to disappear when I initially refreshed the screen. It was very, very hard to reproduce, however with the new versions of everything, (iOS 9, 1.2.9) it has been more common. @hirbod, I am curious as to what types of elements/layer may block the map (and not the html) I make the html a child of the map, so would have expected the html elements to be blocked as well. I will try with 1.3 later today. |
Let's assume following scenario: (or <html> -- will be transparent
<body> -- will be transparent
<div class="page-background"></div>* -- NOT TRANSPARENT
<div> -- will be transparent
<div> -- will be transparent
<div> -- will be transparent
<div id="map"></div>
...
... *this is something that happens e.g. on onsenUI, not a parent node, will not be recognized from plugin Also, elements that where added after the plugin was initialized will not be transparent. refreshLayout() need to be called, sometimes you just need to make it transparent on your own. I'm using OnsenUI, I have a global $rootScope (or use a service) function, which I call everytime I change the view, just to make sure that my "special" div's are transparent. (ons.ready()) - ionic will have for sure it's own ready mechanism, which can be called when it's ready rendering it's content. You should hook on that. Use the DOM inspector and bubble up every parent-node until you find the one which was not set to transparent. After I understand that, it worked perfectly. |
Greetings Inspecting the DOM and manipulating the z-index of the map div (it is set to 0), the map would suddenly appear. Is there an idea value for the z-index? I did not see anything that was above the map that would block it. I will do some additional tests to see what happens when I try manipulating it. |
Actually the z-index should not change anything. The mapview is placed under the webview. Changing the z-index will actually just trigger a redraw inside of webkit, which will indeed fix some visual problems sometimes. White maps = drawing error. I'm very sorry, but the only method to display the map with the ability to place content on it is this way. Otherwise you need to stick on Google Maps JS. I know, this plugin is quite hacky, I don't regret, but it's the only way currently. My time is very limited, but I will try to dig inside of the JS-code and optimize init. I'm sure there will be a better way to detect parent-nodes. |
@hirbod I understand time is the one thing that is very valuable. I have done plenty of programming in C, C++ etc, but very little with Objective C, but I am willing to look into this problem as it is very important to me. If you can tell me where to look in Objective C (or is it js-code), I will do what I can. Is there a way to trigger a redraw of the webkit? As for when my crude tests with CSS it did not appear to affect anything until I changed the CSS itself. |
Try to change z-index of element, or just background-element or something. |
Had some of those errors also today. just pseudo-code init view......
$scope.fixBackground = function(){
$('.page__background').not('.page--menu-page__background').stop().velocity({
backgroundColor: '#eee',
backgroundColorAlpha: 0
});
};
$timeout(function(){
... init maps plugin
$scope.fixBackground() // onsen specific
$rootScope.map.refreshLayout()
},300;) real hacky but after 300 reloads I've never faced a white map again. |
I think that you mean that I should initialize the getMap function and delay the return from plugin.google.maps.event.MAP_READY callback. I'm waiting for the update to xcode but will try that once done. |
In my index.html, I give my main ion-nav-view an id :
then in my map code :
Added the init variable so as to just do this once. @hirbod after trying this native google maps plugin, there is no way that I could go back to the JS library :) What is weird though is that I only call this plugin within a ionic.Platform.ready function so I would have assumed that all the DOM nodes are ready - seems like I am wrong. |
@hirbod I've tried a few timings, I've placed a delay of 300ms and the same result, however when I did 1000ms (or 1sec) the display issue seems to be resolved. I will do some more testing, and will look at googlemaps_cdv_plugin.js more closely. I would think that MAP_READY would not return until it was truly ready. |
The problem still occurs though not as frequently. I will have to check more later. |
Hi @hirbod, I have been looking more into this issue. I've changed the delay to 3000ms and this seems to solve the display issue on iOS, however it is not a very robust solution as I don't know why this works.. Looking for a more robust solution. When I looked at the googlemaps-cdv-plugin.js, I didn't notice anything that seemed odd, except for
Which is toward the end of the App.prototype.getMap. This delay, while small is odd as you would assume that getMaps has completely returned. Also, the underlying objective c call to getMap in GoogleMaps.m does processing for the the webView and sets the backgoundColor
which I think is fine by itself. This is suppose to do things in the background that are trivial. I'm curious as to how quickly I ask this because right below the async call is
Which is significant because it has the potential to use self.mapCtrl before it has not been allocated, or is this a "red-herring", and the timing is insignificant? At this point, I would have to look in xcode and see the timings to make sure these are fine, and read more on the iOS documentaion, but I was wondering if you had insight if this could be a problem, as I know very little of xcode and iOS native programming. |
Hey guys, I am a very similar problem (sorry to bring this up again). I'm using this code:
|
@gregavola I placed the timeout after the return of MAP_READY. It appears that there is some possible delay issues so that when the MAP_READY is returned, it really isn't ready. I would change your code to
or something like that. Please let me know if that works for you. I found that 3000 seemed to be optimal in my case. |
I got another fix (for now, till I find the real issue for this) $scope.fixBackground = function(){
$('.page__background').not('.page--menu-page__background').stop().velocity({
backgroundColor: '#eee',
backgroundColorAlpha: 0
});
// you could also use .animate() or just .css() - but my fixBackground hack is just for OnsenUI
};
$timeout(function(){
var mapDiv = document.getElementById("map_canvas");
if($('#map_canvas').length) {
$('#map_canvas').css('height', (($(window).height() - $('#map_canvas').offset().top - $('.ons-tabbar-inner').height())));
}
$scope.tilt = 50;
$scope.maptype = plugin.google.maps.MapTypeId.ROADMAP;
$rootScope.map = plugin.google.maps.Map.getMap(mapDiv, {
'mapType': $scope.maptype,
'controls': {
'compass': true,
'myLocationButton': false,
'indoorPicker': false,
'zoom': false
},
'gestures': {
'scroll': true,
'tilt': true,
'rotate': true
}
});
$rootScope.map.one(plugin.google.maps.event.MAP_READY, $scope.onMapInit);
}, 300);
$scope.onMapInit = function(){
$scope.fixBackground();
$rootScope.map.clear(); // this fixed everything for me
// now add marker
....
....
}); First I've inited my map inside of a small timeout (300ms), then I will call a one-time trigger of the map-ready event, and then I call the clear() function (even when there is nothing) This is for sure a hack, but I will try to incorporate some of my thoughts into the final .js But I do not have any white map issues anymore |
By the way, I also call something on deviceready (e.g. angular.run()) // we need this workaround because of location.reload
window.onbeforeunload = function(e) {
if($rootScope.map) {
$rootScope.map.clear();
$rootScope.map.remove();
}
};
plugin.google.maps.Map.clear(); // just call on every app-start. Seemed to fix many problems. The unbeforeunload-trigger is important if you want to use cordova-hot-code-push or when you just call a window.location.reload() - this will fix multiple map views being added. |
I just removed all the dispatch_async and dispatch_sync wraps and I do not see any issues and the bug is gone. I will release the next version without the call and we will see how it works.. |
Hope my commit will fix the problems |
quick question what type of problems does calling Map.clear() do? |
It just remove the markers without removing the map |
But you had a comment that it fixed many problems on app start. |
Yes, in case of a reload: window.location.reload() |
Greetings @hirbod , I have been testing 1.3.3 and 1.3.4 with iOS9, and on the iPhone, the problem seems to be resolved. |
The issue was not fixed even with the latest commit. I noticed that sometimes (especially if the internet is slow), webViewDidFinishLoad() in CDVViewController.m gets called AFTER the google map is initialized, which is the root of the problem. By delaying plugin.google.maps.Map.getMap() till AFTER webViewDidFinishLoad(), the issue was solved. NSString* jsString = [NSString stringWithFormat:@"yourJavascriptFunction('%s');", ""]; And then once yourJavascriptFunction() is called, you can safely call plugin.google.maps.Map.getMap(). I hope this helps someone. |
Thanks, but this would require to patch Cordova files. Actually I thought device ready should be safe enough. Maybe there is any way to detect webviewdidload inside of the maps plugin. But what you say seems legit. I also faced some problems (1 of 20 loads resulted in white screen). Weird... |
Turns out this isn't a full-proof solution. I am still getting a white map sometimes. Working to fix this. |
Looks like this is a Google Bug. (as it started to happen since 1.10) I will update to 1.11.0 now
Resolved Issues:
|
1.3.6 is out. Make sure that the SDK-Plugin will be removed when you call |
I have a very unusual problem in which I'm not sure if the problem is with iOS, the plugin or just google maps api.

On iOS 9.1, sometimes the map does not appear. In iOS 8.4 there is no problem.
In examining the logs, there does not appear to be any problems, and when I rotate the display to landscape, the screen is redrawn correctly.
I'm using Cordova 5.2 with 1.2.9 of the googlemaps plugin and am using jquery and jquery mobile though that shouldn't affect the problem.
The html is rendered correctly as can be seen the following picture.
The screen normally looks like

I tried using map.refreshLayout() but it does not cause the screen to be drawn. Is there any other function that I might use to refresh the map? or to see what can be happening with the display?
The text was updated successfully, but these errors were encountered: