How to hide header on scroll in ionic 4?

Issue

I wanted to know how I can hide a header in Ionic 4 by scrolling down the page, and re-show it when scrolling up.

I found many solutions on how to do that, but they all turned out to not working or being out-of-date.

So I collected all piece of information I could find to provide this answer.

Solution

Thanks to this video I got it to work.

First of all call ionic g directive directives/hide-header. You can of course replace directive/hide-header with your own path and name.

hide-header.directive.ts

import { Directive, HostListener, Input, OnInit, Renderer2 } from '@angular/core';
import { DomController } from '@ionic/angular';

@Directive({
    selector: '[appHideHeader]'
})
export class HideHeaderDirective implements OnInit {

    @Input('header') header: any;

    private lastY = 0;

    constructor(
        private renderer: Renderer2,
        private domCtrl: DomController
    ) { }

    ngOnInit(): void {
        this.header = this.header.el;
        this.domCtrl.write(() => {
            this.renderer.setStyle(this.header, 'transition', 'margin-top 700ms');
        });
    }

    @HostListener('ionScroll', ['$event']) onContentScroll($event: any) {
        if ($event.detail.scrollTop > this.lastY) {
            this.domCtrl.write(() => {
                this.renderer.setStyle(this.header, 'margin-top', `-${ this.header.clientHeight }px`);
            });
        } else {
            this.domCtrl.write(() => {
                this.renderer.setStyle(this.header, 'margin-top', '0');
            });
        }

        this.lastY = $event.detail.scrollTop;
    }

}

After that, in your template:

<ion-header #header>
    <ion-toolbar><ion-title>Test</ion-title></ion-toolbar>
</ion-header>
<ion-content scrollEvents="true" appHideHeader [header]="header">
</ion-content>

Take care of the scrollEvents, appHideHeader and the [header] attributes! The last one takes the header element as argument, in this case #header.


Most of the code is the same as shown in the video. I changed the host-property from the @Directive and used the more up-to-date HostListener.

If you want to use the directive in more than one directive, you need to create a SharedModule.

To do so, create the module with ng g module shared. After that, add the HideHeaderDirective to the declarations and the exports array.

shared.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HideHeaderDirective } from './directives/hide-header.directive';


@NgModule({
    declarations: [HideHeaderDirective],
    exports: [HideHeaderDirective],
    imports: [
        CommonModule
    ]
})
export class SharedModule {}

Now add the shared module to all the modules you want to use the directive in.

Note: You cannot import the directive in app.module.ts and use it in a submodule! You have to import the shared module in every direct module you want to use the directive in.

My current versions of node, npm and ionic:

versions

Answered By – bene-we

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published