-
-
Notifications
You must be signed in to change notification settings - Fork 26
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
Proper way to switch between multiple maps on multiple "pages"? #66
Comments
Made an example app.js here, at the bottom, which can reproduce the various crashes. Range exception:
Crash when starting up app again after the above crash:
Another time when starting the app:
app.js var maps = require("ti.googlemaps");
maps.setAPIKey("<YOUR_GOOGLE_MAPS_API_KEY>");
var win = Ti.UI.createWindow({
});
win.open();
var coords = [];
for (var i=0;i<50;i++) {
coords.push({
latitude: i,
longitude: i
});
}
//prebuild annotations
var annos = [];
for (var i=0;i<50;i++) {
var annotation = maps.createAnnotation({
latitude: i,
longitude: i,
title: "title",
subtitle: "subtitle",
// pinColor: "green",
// image: "myPin.png"
});
annos.push(annotation);
}
//create views to switch between
var views = [];
var curr_view;
for (var i=0;i<3;i++) {
views.push(Ti.UI.createView({
backgroundColor: "green",
bottom: 50,
index: i
}));
}
//create buttons for switching views
var buttons = [];
var selected_button = null;
var buttons_view = Ti.UI.createView({
backgroundColor: "red",
height: 50,
bottom: 0,
layout: "horizontal",
});
win.add(buttons_view);
for (var i=0;i<views.length;i++) {
var button = Ti.UI.createButton({
title: "view"+i,
index: i,
width: Math.floor(100/views.length)+"%",
height: Ti.UI.FILL,
backgroundColor: "#aaa",
color: "black",
borderColor: "black",
});
button.addEventListener('click',function(e){
change_view(this.index);
});
buttons[i] = button;
buttons_view.add(button);
}
function change_view(index){
console.log("change_view("+index+")");
if (curr_view && curr_view.index == index) {
console.log("can't change view, already on index "+index);
return;
}
if (selected_button) selected_button.backgroundColor = "#ccc";
selected_button = buttons[index];
selected_button.backgroundColor = "white";
if (curr_view) {
curr_view.mapView.removeAnnotations(annos);
win.remove(curr_view);
curr_view.remove(curr_view.mapView);
curr_view.mapView = null;
}
curr_view = views[index];
curr_view.mapView = maps.createView({
mapType: maps.MAP_TYPE_TERRAIN,
indoorEnabled: false,
indoorPicker: false,
compassButton: false,
myLocationButton: false,
myLocationEnabled: false,
region: {
latitude: coords[0].latitude,
longitude: coords[0].longitude,
zoom: 3
}
});
curr_view.add(curr_view.mapView);
win.add(curr_view);
curr_view.mapView.addAnnotations(annos);
}
change_view(0); |
Yeah, that's a problem and not possible so far, because the annotations are stored in an internal data structure in the map view. |
Oh, I see. What's the best work-around you think? |
Tried an alternate way: Having just one map created at startup, and removing it from one view, then adding it to another view. That doesn't work either; the map just doesn't appear to be added. My idea here was to just reuse the same map, with the same annotations, and hiding/showing the annotations depending on the view. It's beginning to look like the only way I will be able to make this work, is by creating the map view from scratch every time it is used. Edit: Ooops closed it by mistake. |
I just made this example based on the above (see below), but this time the mapview and annotations are created every time the view is changed. It still crashes like above - any ideas? Clicking each view button a few times in rapid succession:
Again switching between views by pressing the buttons (this time slowly):
Crash at app startup after the above caused a crash:
var maps = require("ti.googlemaps");
maps.setAPIKey("<YOUR_GOOGLE_MAPS_API_KEY>");
var win = Ti.UI.createWindow({
});
win.open();
var coords = [];
for (var i=0;i<50;i++) {
coords.push({
latitude: i,
longitude: i
});
}
//create views to switch between
var views = [];
var curr_view;
for (var i=0;i<3;i++) {
views.push(Ti.UI.createView({
backgroundColor: "green",
bottom: 50,
index: i
}));
}
//create buttons for switching views
var buttons = [];
var selected_button = null;
var buttons_view = Ti.UI.createView({
backgroundColor: "red",
height: 50,
bottom: 0,
layout: "horizontal",
});
win.add(buttons_view);
for (var i=0;i<views.length;i++) {
var button = Ti.UI.createButton({
title: "view"+i,
index: i,
width: Math.floor(100/views.length)+"%",
height: Ti.UI.FILL,
backgroundColor: "#aaa",
color: "black",
borderColor: "black",
});
button.addEventListener('click',function(e){
change_view(this.index);
});
buttons[i] = button;
buttons_view.add(button);
}
var busy = false;
function change_view(index){
console.log("change_view("+index+")");
if (busy) {
console.log("BUSY");
return;
}
busy = true;
if (curr_view && curr_view.index == index) {
console.log("can't change view, already on index "+index);
return;
}
if (selected_button) selected_button.backgroundColor = "#ccc";
selected_button = buttons[index];
selected_button.backgroundColor = "white";
if (curr_view) {
console.log("removing mapView from curr_view index: "+curr_view.index);
curr_view.remove(mapView);
win.remove(curr_view);
}
curr_view = views[index];
var mapView = maps.createView({
mapType: maps.MAP_TYPE_TERRAIN,
indoorEnabled: false,
indoorPicker: false,
compassButton: false,
myLocationButton: false,
myLocationEnabled: false,
region: {
latitude: coords[0].latitude,
longitude: coords[0].longitude,
zoom: 3
}
});
curr_view.add(mapView);
var annos = [];
for (var i=0;i<50;i++) {
var annotation = maps.createAnnotation({
latitude: i,
longitude: i,
title: "title",
subtitle: "subtitle",
// pinColor: "green",
// image: "myPin.png"
});
annos.push(annotation);
}
mapView.addAnnotations(annos);
win.add(curr_view);
busy = false;
}
change_view(0); |
@hansemannn Can you tell me if I'm doing something wrong in the latest example above? I try to create the mapview + annotations every time from scratch, but there's still crashes, like when I try to reuse map/annotations. |
I didn't look into multiple maps so far. But I can think that having an array that is used multiple times (even if pushed to multiple times), could cause issues. I would need to re-think the way to organize annotations internally, that's a biggie. |
@hansemannn Alright, I understand and thus why I tried to create both maps and annotations from scratch. But it still does crash, and I have no idea why it's happening. It's not that anything is reused in this case, so it doesn't make much sense to me. |
I see TiShadow there, can you try it without? |
@hansemannn I just tried without TiShadow, running on simulator - it crashes immediately when launching (can see the views and buttons for a fraction of a second). Very weird that it actually can start in TiShadow, but not standalone. The output errors are:
|
|
@hansemannn I added it now and rebuilt (cleaned too), but the iOS location dialog disappears too quickly to accept. I did however go to settings and enabled location for the app. Still crashes on startup with the same errors. |
Another note: Don't (ever) access sub-view references using the dot-assignment ( |
OK but I am not doing that in the latest example above, and it still crashes. |
@hansemannn is there any way I can get you to run the latest example above? To confirm/not confirm if it's also occuring on your end? |
@hansemannn I played around with it some more, and now it doesn't crash, when switching between views. The difference? Using mapView.addAnnotation for each annotation seperately, instead of addAnnotations. So there might be some issues with that particular function. Working example using single addAnnotation, where addAnnotations is commented out (crashes when switching views several times): var maps = require("ti.googlemaps");
maps.setAPIKey("<YOUR_GOOGLE_MAPS_API_KEY>");
var win = Ti.UI.createWindow({
});
win.open();
var coords = [];
for (var i=0;i<50;i++) {
coords.push({
latitude: i,
longitude: i
});
}
//create views to switch between
var views = [];
var curr_view;
for (var i=0;i<3;i++) {
views.push(Ti.UI.createView({
backgroundColor: "green",
bottom: 50,
index: i
}));
}
//create buttons for switching views
var buttons = [];
var selected_button = null;
var buttons_view = Ti.UI.createView({
backgroundColor: "red",
height: 50,
bottom: 0,
layout: "horizontal",
});
win.add(buttons_view);
for (var i=0;i<views.length;i++) {
var button = Ti.UI.createButton({
title: "view"+i,
index: i,
width: Math.floor(100/views.length)+"%",
height: Ti.UI.FILL,
backgroundColor: "#aaa",
color: "black",
borderColor: "black",
});
button.addEventListener('click',function(e){
change_view(this.index);
});
buttons[i] = button;
buttons_view.add(button);
}
var busy = false;
var mapView;
function change_view(index){
console.log("change_view("+index+")");
if (busy) {
console.log("BUSY");
return;
}
busy = true;
if (curr_view && curr_view.index == index) {
console.log("can't change view, already on index "+index);
return;
}
if (selected_button) selected_button.backgroundColor = "#ccc";
selected_button = buttons[index];
selected_button.backgroundColor = "white";
if (curr_view) {
console.log("removing mapView from curr_view index: "+curr_view.index);
mapView.removeAllAnnotations();
curr_view.remove(mapView);
win.remove(curr_view);
mapView = null;
delete mapView;
}
curr_view = views[index];
mapView = maps.createView({
mapType: maps.MAP_TYPE_TERRAIN,
indoorEnabled: false,
indoorPicker: false,
compassButton: false,
myLocationButton: false,
myLocationEnabled: false,
region: {
latitude: coords[0].latitude,
longitude: coords[0].longitude,
zoom: 3
}
});
curr_view.add(mapView);
// var annos = [];
for (var i=0;i<50;i++) {
var annotation = maps.createAnnotation({
latitude: i+i,
longitude: i,
title: "title",
subtitle: "subtitle",
// pinColor: "green",
// image: "myPin.png"
});
//annos.push(annotation);
mapView.addAnnotation(annotation);
}
//mapView.addAnnotations(annos);
win.add(curr_view);
busy = false;
}
change_view(0); |
@hansemannn The other crashes were caused by having both run-on-main-thread and use-app-thinning enabled. Everything works fine with those two disabled (except for mapView.addAnnotations). I apologize for the confusion, I wasn't aware of those "new" parameters. |
That are interesting findings! I pushed some changes that should fix the main-thread issues (the app-thinning shouldn't affect this). The |
Just tested with 2.7.0, works splendidly! Thank you so much for all your work @hansemannn :) |
@bitfabrikken So the one from master (self-built) or from the Releases page? I didn't update that version so far. |
@hansemannn Just a side note, the original example in the first post here, also works now. That is, the example where I only create the annotations once, and then reuse them on subsequent mapViews! This is awesome! |
@hansemannn I'm not sure, I just did "git pull" |
that's from master, thx! Will release a 2.7.1 with that patch then. 🚀 |
I've got this app where I switch between multiple pages (views), that have different maps on them.
In some cases, I need to add the same annotations to them, and in some cases I don't.
Because of this, I prefer to have the annotations "prebuilt" so I can just add them to any map view later on.
Currently I do this:
• Create annotations and store them in e.g. app.annotations
• Show view1: Create new map view, add to view1, add annotations
• Show view2: Remove annotations, remove map view from view1 and null it, hide view1, create map view, add to view2, add annotations
• Show view 1 again: Remove annotations, remove map view from view2 and null it, hide view2, create map view, add to view1, add annotations
This works alright with the ti.map module, but with ti.googlemaps, I often get IndexOutOfRange errors, causing the app to crash.
I'm now wondering if I'm doing something incorrectly, and what the proper way to do this would be?
The text was updated successfully, but these errors were encountered: