Ionic uses Angular’s routing system which allows makes hiding and showing tabs on certain pages while leaving it visible everywhere else makes it easier.
Here at Ibmi Media, as part of our Server Management Services, we regularly help our Customers to perform App related tasks.
In this context, we shall look into the process of hiding and showing tabs on certain pages.
See some tips below.
1. Create a new Ionic Tab Application
First, we will create an Ionic application using the latest Ionic CLI.
$ npm install -g @ionic/cli
Next, we create a new Angular Ionic tab application using to hide tabs from some pages and display it in other pages.
$ ionic start IonicComponents tabs –type=angular
2. Create a new service
Now, we will create the service provider by running the below command.
$ ionic g service tab
Next, we need to import the service into our app.modules.ts provider array, as well as importing it into our app.component.ts file, in our constructor.
app.module.ts
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
...
],
providers: [
TabsService
...
],
bootstrap: [AppComponent],
})
export class AppModule {
}
app.component.ts
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
})
export class AppComponent {
constructor(public tabs: TabsService) {
...
}
...
}
3. Configure the TabsService provider
First we will create a new variable called hideTabBarPages. This is a string array, that we will use to tell Ionic what pages to hide our tab bar on.
hideTabBarPages = [
'login',
'registration',
'forgot-password',
];
Next, in the constructor, we should import the Router and the Platform providers like so:
constructor(private router: Router, private platform: Platform) {
this.platform.ready().then(() => {
console.log('Core service init');
this.navEvents();
});
}
The NavEvents function will handle our navigation events.
navEvents() {
this.router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe((e: any) => {
console.log(e);
this.showHideTabs(e);
});
}
We are using the router.events Observable for filtering out the events so that we only get the NavigationEnd events, and then run another function with the event data. The reason we’re filtering out certain events is that Angular triggers a number of lifecycle events, whenever we navigate to a page. If we didn’t do this, the inner function this.showHideTabs(e) would be called numerous times with every page change.
showHideTabs(e: NavigationEnd) {
const urlArray = e.url.split('/');
const pageUrlParent = urlArray[urlArray.length - 2];
const pageUrl = urlArray[urlArray.length - 1];
const page = pageUrl.split('?')[0];
const hideParamPage = this.routeParamPages.indexOf(pageUrlParent) > -1 && !isNaN(Number(page));
const shouldHide = this.hideTabBarPages.indexOf(page) > -1 || hideParamPage;
try {
setTimeout(() => shouldHide ? this.hideTabs() : this.showTabs(), 300);
} catch (err) {
}
}
~~
The showHideTabs function will handle whether it should show the tabs or hide it depending on the page we navigate to.
The e: NavigationEnd event will have the following information in it.
i. First, we need to get the event URL in a format that we can use it.
ii. Then we will grab the last page URL in the path.
iii. We need to remove the parameters since we only want the page name. The parameters that passing is shown after the ? Character.
iv. The last thing that we need to do in this function is to check if we should hide this particular page or not. Lastly, we will need to actually hide the tabs if, or show them if they’ve been previously hidden.
Basically, it says that if ShouldHide is true, then run this.hideTabs() if shouldHide is false run this.showTabs().
4. Handling Pages with Route Parameters
Route parameters i.e: ‘product-details/:id’ will not automatically work with our current implementation. For that, we need to create a new public variable called routeParamPages, it’s a string array.
routeParamPages: string[] = [
'tabs1',
];
Below, the pageUrlParent is a new variable. This is similar to the pageUrl variable. But instead of grabbing the page, we’re navigating to from the urlArray. We’re going to grab the parent of that page.
const pageUrlParent = urlArray[urlArray.length – 2];
const hideParamPage = this.routeParamPages.indexOf(pageUrlParent) > -1 && !isNaN(Number(page));
This will tell us if the page is a routeParamPage, and if it needs to be hidden.
If the page we are navigating to has any non-numeric characters, this will evaluate to Nan(Not A Number). Lastly, we are checking that the converted Number(page) is not Nan through, isNan(Number(page)). Then we just have to track on an orstatement to our shouldHide variable
const shouldHideTabs = this.hideTabBarPages.indexOf(page) > -1 || hideParamPage;
Create the hideTabs() & showTabs() functions. Here is the code that we add.
public hideTabs() {
const tabBar = document.getElementById('myTabBar');
if (tabBar.style.display !== 'none') tabBar.style.display = 'none';
}
public showTabs() {
const tabBar = document.getElementById('myTabBar');
if (tabBar.style.display !== 'flex') tabBar.style.display = 'flex';
}
We check to make sure that the tabBar is not null. This way we ensure that our service doesn’t throw an error when navigating on a page that doesn’t have a tabBar such as app-login. Flex for if we’re going to show the tabs and none if we’re going to hide them.
Finally, after all the changes the tabService will look like this.
import { Injectable } from '@angular/core';
import { filter } from 'rxjs/operators';
import { NavigationEnd, Router } from '@angular/router';
import { Platform } from '@ionic/angular';
@Injectable({
providedIn: 'root',
})
export class TabsService {
hideTabBarPages = [
'login',
'registration',
'forgot-password',
];
routeParamPages: string[] = [
'tabs1',
];
constructor(private router: Router, private platform: Platform) {
this.platform.ready().then(() => {
console.log('Core service init');
this.navEvents();
});
}
public hideTabs() {
const tabBar = document.getElementById('myTabBar');
if (tabBar.style.display !== 'none') tabBar.style.display = 'none';
}
public showTabs() {
const tabBar = document.getElementById('myTabBar');
if (tabBar.style.display !== 'flex') tabBar.style.display = 'flex';
}
private navEvents() {
this.router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe((e: any) => {
console.log(e);
this.showHideTabs(e);
});
}
private showHideTabs(e: any) {
const urlArray = e.url.split('/');
const pageUrlParent = urlArray[urlArray.length - 2];
const pageUrl = urlArray[urlArray.length - 1];
const page = pageUrl.split('?')[0];
const hideParamPage = this.routeParamPages.indexOf(pageUrlParent) > -1 && !isNaN(Number(page));
const shouldHide = this.hideTabBarPages.indexOf(page) > -1 || hideParamPage;
try {
setTimeout(() => shouldHide ? this.hideTabs() : this.showTabs(), 300);
} catch (err) {
}
}
}
Finally, we will add an ID to the tabBar element in app.component.html
<ion-tab-bar slot="bottom" #myTabBar id="myTabBar">
On checking, we can see that the tabs automatically hide when we navigate to a page in the hideTabBarPages array.
This article will guide you on the steps to hide and show tabs on certain pages. Here, you will see that your tabs automatically hide when you navigate to a page in the hideTabBarPages array.
Ionic 4 uses Angular's #routing system, instead of the #Ionic 3 method of navController. Here, we will be leveraging this change, to allow us to pragmatically hide the tab bar on pages of our choice while leaving it visible everywhere else.