Hello,
I have several Tabs which all lead to different windows. I want to display one MapView in every tab, but as soon as I switch to an other tab, the map disappears. Is there a way to make an element global for all the tabs?
Best Regards, Martin
6 Answers
Accepted Answer
Hi Martin
Unfortunately no - you need (and should) have one per window given how scope works in the apps.
However - you can make you life much easier by;
You can make the code you use re-usable by wrapping everything in a CommonJS format or a function and by passing in parameters and returning the map view.
By using the CommonJS approach (rather than function) to sections of functionality you have much better memory management and ease of coding.
Hope this helps you.
Unless I am missing something your map code is not correctly adding the map to the window in the first place.
//create MapView Ti.App.map = nfm.createMapView({ mapType : Titanium.Map.SATELLITE_TYPE, region : { latitude : 49.293512, longitude : 8.642024, latitudeDelta : 0.002, longitudeDelta : 0.002 }, animate : true, regionFit : true, userLocation : false });should be
//create MapView var mapView = nfm.createMapView({ mapType : Titanium.Map.SATELLITE_TYPE, region : { latitude : 49.293512, longitude : 8.642024, latitudeDelta : 0.002, longitudeDelta : 0.002 }, animate : true, regionFit : true, userLocation : false }); win.add(mapView); //swap win to the window it should appear in .You should then reference
mapView in the future.
You have a number of views that 'pollute' (horrible phrase but correct) the Ti/Titanium name space, your app should have its own.
An example;
var app = {}; app.map = nfm.createMapView({ mapType : Titanium.Map.SATELLITE_TYPE, region : { latitude : 49.293512, longitude : 8.642024, latitudeDelta : 0.002, longitudeDelta : 0.002 }, animate : true, regionFit : true, userLocation : false }); win.add(app.map); //swap win to the window it should appear in . //also app.someFunction = function (fn, ln) { return fn + ' ' + ln; } alert(app.someFunction('Some', 'One'));Helps reduce memory issues and the pollution. Sorry if this last bit taught you to suck eggs, but thought worthwhile pointing out.
You are heading in the right direction, and you should use commonjs but you dont have to. If you are using Android, please be aware that you can only have one mapView so it must be a global object.
maybe if you provide some code, it might be easier to diagnose your problem?
Here is some of the code. searchRoomWindow is the first active tab and shows the map. as soon as I switch to eg navigationWindow.js, the map disappears...
app.js
Ti.API.info('app.js'); var initializer = require('initialize'); var search = require('search'); var database = require('database'); var floorSwitch = require('floorSwitch'); var nfm = require('netfunctional.mapoverlay'); //create MapView Ti.App.map = nfm.createMapView({ mapType : Titanium.Map.SATELLITE_TYPE, region : { latitude : 49.293512, longitude : 8.642024, latitudeDelta : 0.002, longitudeDelta : 0.002 }, animate : true, regionFit : true, userLocation : false }); var tabGroup = Ti.UI.createTabGroup(); var roomWin = Titanium.UI.createWindow({ url:'windows/searchRoomWindow.js' }); var roomTab = Ti.UI.createTab({ active:true, title:'Search Room', window: roomWin }) var officeWin = Titanium.UI.createWindow({ url:'windows/searchOfficeWindow.js' }); tabGroup.addTab(roomTab); var officeTab = Ti.UI.createTab({ title:'Search Office', window: officeWin }) tabGroup.addTab(officeTab); var poiWin = Titanium.UI.createWindow({ url:'windows/showPoiWindow.js', }); var poiTab = Ti.UI.createTab({ title:'Show POIs', window: poiWin }) tabGroup.addTab(poiTab); var navigationWin = Titanium.UI.createWindow({ url:'windows/navigationWindow.js' }); var navigationTab = Ti.UI.createTab({ title:'Navigation', window: navigationWin }) tabGroup.addTab(navigationTab); tabGroup.addEventListener('open',function() { // set background color back to white after tab group transition Titanium.UI.setBackgroundColor('#fff'); }); tabGroup.setActiveTab(0); tabGroup.open();searchRoomWindow.js
var nfm = require("netfunctional.mapoverlay"); var search = require('../search'); // add map to the window Titanium.UI.currentWindow.add(Ti.App.map); Ti.App.searchBar = Ti.UI.createSearchBar({ barColor : '#000', showCancel : false, width : '80%', height : '100%', top : 0, left : 0, hintText : "e.g. WDF01,CE.10" }) Ti.App.searchBar.blur(); Ti.App.searchButton = Ti.UI.createButton({ title : 'Go', top : 0, height : '100%', width : '20%', }) var searchView = Ti.UI.createView({ layout : 'horizontal', top : 0, width : '100%', height : 70, left : 0 }); searchView.add(Ti.App.searchBar); searchView.add(Ti.App.searchButton); Titanium.UI.currentWindow.add(searchView);navigationWindow.js
Ti.API.info('open Tab: Navigation') var search = require('../search'); var dijkstra = require('../dijkstra'); // add map to the window Titanium.UI.currentWindow.add(Ti.App.map); navigationBarFrom = Ti.UI.createSearchBar({ barColor : '#000', showCancel : false, width : '80%', height : '50%', top : 0, left : 0, hintText : "From" }) navigationBarFrom.blur(); navigationBarTo = Ti.UI.createSearchBar({ barColor : '#000', showCancel : false, width : '80%', height : '50%', top : '50%', left : 0, hintText : "To" }) navigationBarTo.blur(); var navigateButton = Ti.UI.createButton({ title : 'Go', top : 0, right : 0, height : '100%', width : '20%', }) var navigationView = Ti.UI.createView({ top : 0, width : '100%', height : 140, }); navigationView.add(navigationBarFrom); navigationView.add(navigationBarTo); navigationView.add(navigateButton); Titanium.UI.currentWindow.add(navigationView);
You can build a CommonJS module to manage your mapview. Keep in mind that you can only have one mapview per app in android. It's a difficult restriction to live with, but it can be done if you're careful.
So you build a CommonJS class that has a static member variable that is the single instance of the mapview. Then you can add it to views and remove it from views.
Here's just a little to get you started:
MyMapView.js:
var _mapview = null; function MyMapView () { if (_mapview == null) { _mapview = Ti.Map.createView ({...}); } return _mapview; } module.exports = MyClass;Now in your code, any time you need to access the single instance, do this:
var MyMapView = require ('MyMapView'); var mv = new MyMapView();You'll get back that same single instance everywhere. All without using global variables.
If you're doing it on tabs, it gets trickier, because you have to listen for events when the user changes tabs, and then remove the mapview from the previous tab and put it on the new tab. Again, it's tricky, but it can be done. Use the 'focus' event on the tabgroup to capture this event.
To read more about CommonJS and OO design in Titanium, I recommend these articles
I tried Jason's solution: So in order to protect the mapView, I wrote an Eventlistener that removes the mapView everytime when a FocusEvent on a Tab gets fired. The Problem is: When switching to another Tab, the content of the Tab loads first, then the event gets fired. I need to switch this sequence...
Your Answer
Think you can help? Login to answer this question!