Open mstratiev opened 6 years ago
Found this same issue. Simply switching out of the app and coming back in seems to break it. Anyway to re-initialize?
My package.json if it helps.
{ "description": "MapTest", "license": "UNLICENSED", "readme": "NativeScript Application", "nativescript": { "id": "org.nativescript.MapTest", "tns-android": { "version": "4.0.1" }, "tns-ios": { "version": "4.0.1" } }, "scripts": { "lint": "eslint \"app/**/*.js\"" }, "dependencies": { "nativescript-bitmap-factory": "^1.7.1", "nativescript-carousel": "^3.1.1", "nativescript-checkbox": "^3.0.3", "nativescript-dev-webpack": "^0.11.0", "nativescript-feedback": "^1.1.2", "nativescript-geolocation": "^4.2.6", "nativescript-google-maps-sdk": "^2.6.0", "nativescript-https": "^1.0.1", "nativescript-imagecropper": "^1.0.1", "nativescript-imagepicker": "^6.0.1", "nativescript-iqkeyboardmanager": "^1.3.0", "nativescript-permissions": "^1.2.3", "nativescript-plugin-firebase": "^6.0.2", "nativescript-secure-storage": "^2.2.2", "nativescript-theme-core": "~1.0.4", "nativescript-timedatepicker": "^1.2.1", "tns-core-modules": "^4.0.0" }, "devDependencies": { "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", "clean-webpack-plugin": "~0.1.19", "copy-webpack-plugin": "~4.3.0", "css-loader": "~0.28.7", "extract-text-webpack-plugin": "~3.0.2", "lazy": "1.0.11", "nativescript-dev-sass": "^1.5.0", "nativescript-worker-loader": "~0.8.1", "raw-loader": "~0.5.1", "resolve-url-loader": "~2.2.1", "sass-loader": "~6.0.6", "uglifyjs-webpack-plugin": "~1.1.6", "webpack": "~3.10.0", "webpack-bundle-analyzer": "^2.9.1", "webpack-sources": "~1.1.0" } }
After testing further, this may be connected to the TabView as you mentioned. Having any tab open that isn't the map retains the map when the app resumes. However, if you have the map tab loaded when you suspend the app, it loses it's data on resume.
@mstratiev I managed a temporary workaround by adding a resumeEvent listener on the application in tab.js, then select the map tab frame and navigate ie:
var resumeListener = application.on(application.resumeEvent, (args) => { if(application.android){ var aR = Frame.getFrameById('mapTabFrame'); aR.navigate({ moduleName: 'map/map', clearHistory: true, backstackVisible: false }); } });
This basically forces the map frame to reload any time the application is resumed in android. Not ideal, though.
Thank you, I will give it a try later and see, if that would do the trick. If that would not help, I am rethinking to recreate the whole fragment in code on app resume or remove the whole tab altogether from android and use something custom-made that would not exhibit such issues.
@mstratiev unfortunately, my solution doesn't work as I'd like it to. When app resumes, according to the logic above it creates another instance, ie. you can tap back when the app resumes, and you'll see a 'secondary' map.
I think we are dealing with multiple instances of the mapView somewhere.
@ogmedia Thank you for the feedback and getting back. We will be migrating to react-native, as much as I like my friends from Telerik, since we are having multiple issues with the development, performance and 3-rd party plugins support and bug fixes. However, if I find a proper workaround for this issue with the map, I will get back to this thread.
@mstratiev I achieved similar behavior of TabView using SegmentedBar, with no issues with the map.
@aeroefeuno The problem is that I want proper translations between tabs and sliding etc. I doubt that we could painlessly achieve that with the segmented bar approach.
I have the same problem with a disappearing map inside TabView when using {N} with Angular. As a workaround I managed to make it work with *ngIf directive for MapView with a boolean variable changing inside application's suspend and resume events. This way the map is recreated on resume.
applicationOn(resumeEvent, (args: ApplicationEventData) => {
this.mapVisible = true;
});
applicationOn(suspendEvent, (args: ApplicationEventData) => {
this.mapVisible = false;
});
@JakubPawlak did you put the mapVisible property directly on the MapView component? I have tried to implement your solution and I am not able to get it to work.
Sorry for a late response. I used ngIf on the MapView like this: `<MapView ngIf="mapVisible">`
@JakubPawlak where does you put the application functions? and how do you connect to the mapVisible element?
I didn't notice the mapping in my import statement. You can subscribe to application events importing from application module. I have the Angular component with the MapView in my template and below is the sample code of the component. Binding to the mapVisible variable is done with a basic Angular binding logic.
import {Component, OnDestroy} from "@angular/core";
import {on, off, resumeEvent, suspendEvent} from "application";
@Component({
moduleId: module.id,
selector: "map",
templateUrl: "./map.component.html"
})
export class MapComponent implements OnDestroy {
mapVisible: boolean = true;
constructor() {
on(resumeEvent, (args: ApplicationEventData) => {
this.mapVisible = true;
});
on(suspendEvent, (args: ApplicationEventData) => {
this.mapVisible = false;
});
}
onDestroy() {
off(resumeEvent);
off(suspendEvent);
}
}
ok thanks for your detailed answer but when app fire on resume map is still blank, i am very stuck on this issue.
P.s. i have the map in a tabview, if that matter
@Toq97 Could you share a sample project on github?
Hi!, I have the same issue, any update?
Try redirecting to other page before application.suspendEvent, then redirect again to the current page:
In app.js:
application.on(application.suspendEvent, (args) => {
if (frameModule.topmost() && frameModule.topmost().currentEntry) {
let moduleName = frameModule.topmost().currentEntry.moduleName;
console.log("application.suspendEvent");
if (moduleName == "views/noticias" ||
moduleName == "views/lugares") {
frameModule.topmost().navigate({
moduleName: "views/suspend-tmp",
context: {
actualPage: moduleName
}
});
}
}
});
In suspend-tmp.js:
var actualPage;
const frameModule = require("tns-core-modules/ui/frame");
const getFrameById = require("tns-core-modules/ui/frame").getFrameById;
function onNavigatingTo(args) {
const page = args.object;
// primeraCarga = true;
if (page.navigationContext)
actualPage = page.navigationContext.actualPage;
}
exports.onNavigatingTo = onNavigatingTo;
function onPageLoaded(args) {
// global.SetActualizarAdjuntos(false);
// if (primeraCarga) {
// primeraCarga = false;
//const frame = getFrameById("frmRoot");
console.log("suspend-tmp: Yendo a views/tab-menu");
frameModule.topmost().navigate({
moduleName: actualPage,
});
// }
}
exports.onPageLoaded = onPageLoaded;
That worked for me.
@JakubPawlak Your solution is work properly, just one thing, in my case I had to add also a ngzone.run before switich mapVisible variable status
on(resumeEvent, (args: ApplicationEventData) => {
this.ngZone.run( () => {
this.mapVisible = true;
})
});
on(suspendEvent, (args: ApplicationEventData) => {
this.ngZone.run( () => {
this.mapVisible = false;
})
});
On android (7.0), when the application is suspended and resumed afterwards, the map tiles, markers etc. are not rendered. The MapView itself is shown, but only logo and controls. It is working fine on initial load of the view.
The map is placed in a TabView, using pure latest Nativescript. Any further information needed will be provided.