How to hold back twice to exit


#1

I try to learn from forum, But it looked like an old version of ionic2.

I can’t make it work with last Ionic2 version.

Like this code, I can registerBackButtonAction, And yes it’s work to hold back twice to exit application.

But in push page it can’t hold back to go back to last page.

      let rootScope = {
        backButtonPressedOnceToExit: false
      };
      this.platform.registerBackButtonAction(() => {
        if (rootScope['backButtonPressedOnceToExit']) {
          this.platform.exitApp();
        }
        else {
          rootScope['backButtonPressedOnceToExit'] = true;
          this.toastCtrl.create({
            message: "Press back button again to exit",
            duration: 2000
          }).present();
          setTimeout(()=>{
            rootScope['backButtonPressedOnceToExit'] = false;
          },2000);
        }
        return false;
      },101);

How to solve this problem?


#2

Here’s what I use

platform.registerBackButtonAction(() => {
	const overlayView = this.app._appRoot._overlayPortal._views[0];
	if(overlayView && overlayView.dismiss) {
		overlayView.dismiss();
	} else {
		let nav = this.app.getActiveNav();
		if(nav.canGoBack()){
			nav.pop();
		} else if(this.lastBack + 500 < Date.now()) {
			this.platform.exitApp();
		}
	}
	this.lastBack = Date.now();
});

The back button will

  • Dismiss modals/dialogs
  • Go back to the previous view in the nav stack
  • If in the root, close the application, UNLESS the user seems to have been spamming the back button (500ms delay)

E.g. if the user is in a nav stack with 3 pages, spams the back button to get back to the first one, the app wont close when he makes it to the last page. If he waits 500ms and clicks back again, it closes the app.

I hope I understood the question correctly and that this can be of use!


#3

i would do a little bit cleaup work:

checkout https://github.com/driftyco/ionic/issues/6982#issuecomment-254740855 how to retriev active view overlays and modals :wink:

platform.registerBackButtonAction(() => {
  const overlay = this.ionicApp._overlayPortal.getActive();
  const nav = this.app.getActiveNav();

  if (overlayView && overlayView.dismiss) {
    overlayView.dismiss();
    return;
  }
  if (nav.canGoBack()) {
    nav.pop();
    return;
  }
  if (Date.now() - this.lastBack < 500) {
    this.platform.exitApp();
  }
  this.lastBack = Date.now();
});

#4

Well, now it doesn’t set this.lastBack in order to prevent the app from being closed when the back button is being spammed, because of the returns :wink:

Edit: Cleaned it up and using this myself now

platform.registerBackButtonAction(() => {
	const overlay = this.app._appRoot._overlayPortal.getActive();
	const nav = this.app.getActiveNav();

	if(overlay && overlay.dismiss) {
		overlay.dismiss();
	} else if(nav.canGoBack()){
		nav.pop();
	} else if(Date.now() - this.lastBack > 500) {
		this.platform.exitApp();
	}
	this.lastBack = Date.now();
});

Edit 2: But yeah, if you want the app to exit when clicking twice, change the > 500 to < 500, 500 being the duration/delay. Though I personally think the behavior of not closing the app when the back button is being spammed is much better.

Edit 3: If you want to keep both the “don’t close on spam” and “close with 2 taps”, use this

platform.registerBackButtonAction(() => {
	const overlay = this.app._appRoot._overlayPortal.getActive();
	const nav = this.app.getActiveNav();
	const closeDelay = 2000;
	const spamDelay = 500;

	if(overlay && overlay.dismiss) {
		overlay.dismiss();
	} else if(nav.canGoBack()){
		nav.pop();
	} else if(Date.now() - this.lastBack > spamDelay && !this.allowClose) {
		this.allowClose = true;
		let toast = this.toastCtrl.create({
			message: this.translate.instant("general.close_toast"),
			duration: closeDelay,
			dismissOnPageChange: true
		});
		toast.onDidDismiss(() => {
			this.allowClose = false;
		});
		toast.present();
	} else if(Date.now() - this.lastBack < closeDelay && this.allowClose) {
		this.platform.exitApp();
	}
	this.lastBack = Date.now();
});

Not sure if there’s a neater way of writing that… lol


Unregister back button action
How to show toast before closing app in ionic latest version?
How to set double touch to exit app in ionic 2?
Confirm Exit with device back button in ionic
Hardware Backbutton Service
How to avoid the hardware back button to close a modal view in Android?
#5

What is this.app ?


#6
import { App } from 'ionic-angular';

#7

Wow, This work.
Thank you very much.


#8

Hey just an FYI, change

} else if(Date.now() - this.lastBack > spamDelay && Date.now() - this.lastBack < closeDelay && this.allowClose) {

to

} else if(Date.now() - this.lastBack < closeDelay && this.allowClose) {

otherwise if you tap the back button too fast after getting the toast, it wont close :stuck_out_tongue:


#9

ehhhm yeah because you do not need to set lastBack, when you found something to close :wink:


#10

But the purpose of the lastBack is to see when the button was last pressed, and if it was pressed within the past 500ms we don’t want to show the toast or exit the app, in case they were spamming the back button to just go back to the root :stuck_out_tongue: So it needs to be set after each press, otherwise it’s pretty much pointless to have it at all. I suppose it could be renamed to lastPress or something, cause it doesn’t actually resemble when we last went back a page, but when the last press was in general.


#11

What is lastBack?


#12

lastBack = Date.now();


#13

thank you so much, it’s work for me.


#14

red mark on allowClose …
how to define allowClose?
thanks in advance