1

All the below testing and coding is done for Android phone.

I have created a new tabs project using ionic tabs. And I have 4 tabs at the bottom right now. Now the problem is I clicked on another tab no the view and then try to use the default SwipeToGoBack gesture in the phone and that does nothing.

If I go into any other page then the back gesture works fine, but when I am in the 4 pages of the tabs, it does not work.

I tried below options:

<ion-router-outlet id="main" [swipeGesture]="true"></ion-router-outlet>

IonicModule.forRoot({
    swipeBackEnabled: true
  }

But those did not help. I can even close the side menu bar opened by swipe back. But can not go to the previous tab by swiping back on phone. Even not able to close the app.

If the application is opened and no other tabs were clicked and I do the swipe back gesture then the app closes, but as soon as I click on other tabs then I can not even come out of the application.

I also tried adding back button listeners from the platform but that also did not help. I added below code part in the tabs.page.ts:

this.platform.backButton.subscribe(() => {
  navigator.app.exitApp();
});

Any help on how to go back to the previous tab on swipe back gesture on phone and finally close the app if no previous tab history?

Links already tried:

Harry Joy
  • 58,650
  • 30
  • 162
  • 207

1 Answers1

4
export class TabsPage {
  navigationProccess:Array<any> = [];
  lastTabName:string = "";
  currentBack:string = "";
  constructor(private platform: Platform,private router:Router,private navctrl:NavController) {

    this.router.events.subscribe((event:RouterEvent)=>{

      if(event.url !== undefined){
        if(this.lastTabName !== event.url && event.url !== this.currentBack){
          // we put last tab name not equal event.url so the event don't go twice through array
          // we put event.url not equal current back that is since when navcontroll in back button go back its considered a router event and we don't need it to be inserted again
          this.pushTabHistory(event.url);
        }
        this.lastTabName = event.url;
      }
    });

    this.platform.backButton.subscribeWithPriority(99999999,async()=>{
      let pushHistoryCount = this.navigationProccess.length;
      if(this.router.url.includes('tabs') == true && pushHistoryCount > 1){
        let url = this.navigationProccess[pushHistoryCount-2].url;
        this.navigationProccess.splice(pushHistoryCount-1, 1);
        this.currentBack = url;
        //currentBack should be assigned before navgiate back
        this.navctrl.navigateBack(url);
      }
    })

  }

  pushTabHistory(tabName:string){
    let navHistory = {
      url:tabName
    };
    this.navigationProccess.push(navHistory)
  }
}

Mate i've edited my answer and you where right. Tabs don't have routeroutlet.cangoBack() since tabs and tabs/tab1ortab2ortab3 are considered one level and can't go backward. Here i created the way to make navigation history inside array and go back and forward from this array but subscribe back is from tabs page and i make it like that since you could making it just for testing.

But As an advanced way here we go -> 1) Create A service tabnav:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class TabnavService {
  public navigationProccess:Array<any> = [];
  public lastTabName:string = "";
  public currentBack:string = "";
  constructor() { }

  pushTabHistory(tabName:string){
    let navHistory = {
      url:tabName
    };
    this.navigationProccess.push(navHistory)
  }
}

2)Inside Your TabsPage:

import { TabnavService } from './../services/tabnav.service';
import { Router, RouterEvent } from '@angular/router';
import { Component } from '@angular/core';
import { NavController, Platform } from '@ionic/angular';

@Component({
  selector: 'app-tabs',
  templateUrl: 'tabs.page.html',
  styleUrls: ['tabs.page.scss']
})
export class TabsPage {

  constructor(private platform: Platform,
    private router:Router,
    private tabNavService:TabnavService) {

      if(this.platform.is('android')){
        this.router.events.subscribe((event:RouterEvent)=>{

          if(event.url !== undefined){
            if(this.tabNavService.lastTabName !== event.url && event.url !== this.tabNavService.currentBack){
              // we put last tab name not equal event.url so the event don't go twice through array
              // we put event.url not equal current back that is since when navcontroll in back button go back its considered a router event and we don't need it to be inserted again
              this.tabNavService.pushTabHistory(event.url);
            }
            this.tabNavService.lastTabName = event.url;
          }
        });
      }
  }


}

3) In app.component.ts :

import { TabnavService } from './services/tabnav.service';
import { Component, ViewChild } from '@angular/core';

import { Platform, IonRouterOutlet, NavController } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { Router } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss']
})
export class AppComponent {
  @ViewChild(IonRouterOutlet,{static:false}) routerOutlet:IonRouterOutlet;
  constructor(
    private platform: Platform,
    private splashScreen: SplashScreen,
    private statusBar: StatusBar,
    private router:Router,
    private navctrl:NavController,
    private tabNavService:TabnavService
  ) {
    this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();


      this.platform.backButton.subscribeWithPriority(99999999,async()=>{
        let pushHistoryCount = this.tabNavService.navigationProccess.length;
        if(this.router.url.includes('tabs') == true && pushHistoryCount > 1){
          let url = this.tabNavService.navigationProccess[pushHistoryCount-2].url;
          this.tabNavService.navigationProccess.splice(pushHistoryCount-1, 1);
          this.tabNavService.currentBack = url;
          //currentBack should be assigned before navgiate back
          this.navctrl.navigateBack(url);
        }else if(this.router.url.includes('tabs') == true && pushHistoryCount <2){
      // here is the array less than 2 which is one (you could make it ==0 but i make it if app glitches or something)
      //so if app is on main start point it exit on back pressed
      navigator['app'].exitApp();
    }
      });


    });
  }
}

And Thats All ^^ . Any Help Just comment here again ^^.

Mostafa Harb
  • 1,558
  • 1
  • 6
  • 12
  • I tried that and it did not help. basically I want to go back to the previously selected tab when the back gesture is made. – Harry Joy Mar 13 '20 at 13:03
  • Ok wait an hour and will send you the the required code. – Mostafa Harb Mar 13 '20 at 13:18
  • @HarryJoy i've eddited my answer as you want ^_^. – Mostafa Harb Mar 13 '20 at 17:00
  • 1
    Thank you so much for this, you saved my bacon at the last minute when our testers discovered the hardware back button wasn't working in our tabview based app. – langauld Jul 16 '21 at 02:00
  • @HarryJoy the code could be the same but instead of wrapping the logic in back button, you could just create a gesture from this link https://ionicframework.com/docs/utilities/gestures and wrap the logic that is inside back button into you gesture.. – Mostafa Harb Dec 16 '22 at 18:43