Google Maps not displayed on Navigation

I have used ionic-native Google Map in my application and everything works fine till i have my map as my starting screen. But I wish to open the map on navigation. In this case, the map falls underneath my starting screen. How to make my starting screen transparent on navigation. Somebody please help.

Hey, I had the same problem.

As of version 1.2.0, you can put any HTML element on top of the map. You need to understand how this works.

The map is a native view, not related to JavaScript. It means the map and the browser are different views, the map is not rendered inside the browser view, such as HTML.

In order to put HTML content on top of the map, the map places itself under the browser-view. HTML background of every single parent node must be transparent (rgba(0,0,0,0)); the plugin changes this automatically for you. Keep in mind that absolute positioned elements with width and height set to 100% will not be recognized as parent-nodes (when there are not wrapped around the map) and need to set to transparent manually. Please use the search function for more infos.

If you want to change the background color of your app, use map.setBackgroundColor().

https://camo.githubusercontent.com/4daf1432af1d7b946559a32d9922be7353bcc1ae/68747470733a2f2f676f6f676c6564726976652e636f6d2f686f73742f304231454366715443634c45385230683654336449645746424f484d2f6d656368616e69736d2e706e67

1 Like

Hi fishgrind, thanks for your advise, but google.maps.Map doesn’t have a setBackgroundColor() function. I don’t understand what you mean in your post?

I think this may answer my question:

I’m a bit confused. I am using google.maps.Map, but the above article talks about plugin.google.maps.Map. Which should I use?

If I use plugin.google.maps.Map, I get:

[ts] 
Cannot find name 'plugin'.
any

If I use google.maps.Map, then backgroundColor() is undefined.

let mapOptions = {
  center: bound.getCenter(),
  maxZoom: 15,
  backgroundColor: 'transparent',
  mapTypeId: google.maps.MapTypeId.ROADMAP
};
var htmlElement: HTMLElement = document.getElementById("map");
this.map = new google.maps.Map(htmlElement, mapOptions);

what i was trying to explain:

if you have the map on the starting screen, the map is really rendered underneath your app, as ionic app runs in a webview. The plugin makes sure the startscreens css background color is transparent.

All works well and you see a map.

Now you try load a map in a page you navigated to (popped on top of your root)

The plugin makes sure the popped view and rootview become transparent so you can see the map. However this doesn’t always go right. Check the dom with the chrome developer tools and change the backgrounds in your webview to transparant one by one starting from the top-most view, you will see the map showing through after a while. Now find out why they aren’t being made transparent by the plugin and you should be fine!

Also make sure your #map div is already set to transparent in your css

#map{ background-color: rgba(0,0,0,0) }

2 Likes

Hi fishgrind, thanks for your advise. It makes sense what you say, however I am struggling to get the map to display even though I think its background is set to transparent.

It loads correctly the first time, but then if I navigate to the back again, the map is just white.

Do you know what I am doing incorrectly?

html

<ion-card id="map" class="e-map" *ngIf="fromSearch"></ion-card>

scss

.e-map{ background-color: rgba(0,0,0,0) }

When the map works, the html looks like:

<ion-card id="map" class="e-map" style="position: relative; background-color: rgb(229, 227, 223); overflow: hidden;">
<div class="gm-style" style="position: absolute; left: 0px; top: 0px; overflow: hidden; width: 100%; height: 100%; z-index: 0;">

But when it doesn’t:

<ion-card id="map" class="e-map"></ion-card>

So It looks like the map is not being loaded onto the DOM I think when I navigate to it?

When I load the map, it finds the htmlElement both times (i.e. it’s not undefined):

var htmlElement: HTMLElement = document.getElementById("map");

i will try test your code just now.

Remember though that the map is never loaded in your DOM as it is a native element and doesn’t work in a webview like the rest of your Ionic app.

The webview/ionic part just sits on top the map like a layer. Thats why you need all transparency.

The problem is probably when you navigate away somewhere a layer loses its transparancy again.

A quick simple test would be to add color variable to your app.variable.scss (APP_FOLDER/app/theme/app.variable.scss) to overide your background

add this line: $background-color: #F60;

if the part that was white is now orange you would know its a transparancy issue for sure and just use developer console to figure out which view is the problem.

As soon as i am near my pc i will test your code

1 Like

Thanks, did the test ($background-color: #F60;) quickly. Everything is orange, except when the map does load, it is the map. When the map does not load, the ion card is also orange.

So that means it is a transparency you say. I will play around with Firebug to try get some answers.

with $background-color: #F60; set:

ion-card {
    background: #f60 none repeat scroll 0 0;

without:

ion-card {
    background: #fff none repeat scroll 0 0;

So I thought this may work, but it still just displays a white/blank ion card:

ion-card {
    background: transparent none repeat scroll 0 0;

When the map works:

ion-card {
background: transparent none repeat scroll 0 0;

but it is overriden (i.e. has a line through it). So I guess the map is imposing its own background

instead of using transparant try using rgba(0,0,0,0)

could make a difference

I tried that:

ion-card {
    background: rgba(0, 0, 0, 0) none 

And in Firebug, when I hover over the style, I see it is transparent. But it looks like there is no map beneath I think. I think that google maps is not getting applied to the ion-card at all, because when it works this style gets overriden by the maps. I may be wrong.

This is my issue

This is not a solution to my problem, but may fix other peoples issue.

  private resizeMap(): void {
    if (this.map) {
      google.maps.event.trigger(this.map, 'resize');
    }
  }

hey, tried your code had some problems too. This worked for me.

add this to your css:

ion-app._gmaps_cdv_ .nav-decor{ background-color: transparent !important; }

now the hard part.

as soon as you navigate/pop the view over your root, make sure your rootpage becomes hidden and when you use the back button make sure its visible again.

This should solve it. It’s kind of hackish but works, unless someboddy else has a better solution you can use that for now. If you have a lot of views on your stack this is pretty useless i guess.

something like this works:

rootpage html give your ion-content an id:

<ion-content id="rootpageorsomething">

then in your .ts file this is where your button points

iAmCallingThis() { document.getElementById("rootpageorsomething").hidden = true this.nav.push(PageWithMap, { }) }

a beter solution is probably when you enter the view, get the stack count, subtract 1 and in a loop set them to opacity 0

document.getElementsByClassName("rootpageorsomething")[xx].setAttribute("style", "opacity:0");

this way everything below the current view is hidden…

Hey, I’ve got the similar issue using iOS and can you tell me how to manage that when you use the back button to make it visible again? Is it connected with this.nav.pop?

Try using View controller

http://ionicframework.com/docs/v2/api/components/nav/ViewController/

But unfortunately there is a bug when you use the tabs and on one side you have the tab that is directly opening the map and a button that is pushing to it from home(root) page-> when you first open the tab with the map it is working but after launching the button from the home page that is pushing to the map page, after that, it is not opening from tab anymore but only from the button. Any ideas about this? Thank you very much

Tabs where generated from ionic starter tabs --v2

map.ts

import {Component} from '@angular/core';
import {NavController, Platform} from 'ionic-angular';
import {GoogleMap, GoogleMapsEvent, GoogleMapsLatLng, Geolocation} from 'ionic-native';
@Component({
  templateUrl: 'build/pages/map/map.html'
})
export class MapPage {

map: GoogleMap;

constructor(public navCtrl: NavController, private platform: Platform) {
	platform.ready().then(() => {
		this.loadMap();
	});
}

loadMap(){
Geolocation.watchPosition().subscribe((position) => {

 	let location = new GoogleMapsLatLng(position.coords.latitude, position.coords.longitude);

	this.map = new GoogleMap('map', {
	  'backgroundColor': 'white',
	  'controls': {
	    'compass': true,
	    'myLocationButton': true,
	    'indoorPicker': true,
	    'zoom': true
	  },
	  'gestures': {
	    'scroll': true,
	    'tilt': true,
	    'rotate': true,
	    'zoom': true
	  },
	  'camera': {
	    'latLng': location,
	    'tilt': 30,
	    'zoom': 15,
	    'bearing': 50
	  }
	});

	this.map.on(GoogleMapsEvent.MAP_READY).subscribe(() => {
		console.log('Map is ready!');
	});
	});

}
}

map.html:

<ion-content class="mapHome">
   <div id="map"></div>
</ion-content>

map.scss:

ion-app._gmaps_cdv_ .nav-decor{
background-color: transparent !important;
}

.mapHome {

#map {
	height: 100%;
     }
}

and root files:
temp.ts:

import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';
import {MapPage} from '../map/map';

@Component({
  templateUrl: 'build/pages/temp/temp.html'
})
export class TempPage {
  constructor(public navCtrl: NavController) {

}

footerTapped() {
  this.navCtrl.push(MapPage);
    }
}

temp.html

<ion-content padding>
  <p>Temp page goes here</p>
</ion-content>
<ion-footer class="bar-positive tabs">
<button (click)="footerTapped()" no-paddin no-margin full>
    I'LL BE THERE!
</button>

I found this thread useful (thanks everyone!) – and resorted to this hack for now. Continuing the example, this ultimately worked pretty well for me:

  ionViewDidLeave() {
    console.log('did leave');
    document.getElementById('rootpageorsomething').hidden = true;
  }
  ionViewWillEnter() {
    console.log('will enter');
    document.getElementById('rootpageorsomething').hidden = false;
  }

It uses the navigation lifecycle event callbacks in the .ts of the root page to make sure it’s hidden on exit/entry.

Seems like the plugin still needs some work yet to be aware of how Ionic handle nav views :-/

2 Likes

Glad it helped, it is a little hacky but works fine indeed!

1 Like