Building A Shrinking Header Directive In Ionic 2



I searched over the internet on how to create shrinking header in ionic 2 for over two days, I found this npm package unfortunately it didn't work for ionic 2 RC5.

I finally found this really good article by Josh Morony where he explained how to create directive in ionic 2.
Based on Josh's article, am going to show you how a shrinking header can be done in ionic 2.

This article assumes that you already familiar with ionic 2.

Let's start by creating a new blank ionic 2 by running the following command:

ionic start ion2-shrinking-header blank --v2


Next, run this command to generate our directive:
ionic g directive shrink-header


This will generate the directive in the components folder for us, but we still need to set it up in the app.module.ts file.

So add it to your src/app/app.module.ts to reflect the following:

import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { ShrinkHeader } from '../components/shrink-header/shrink-header';

@NgModule({
  declarations: [
    MyApp,
    HomePage,
    ShrinkHeader
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}]
})
export class AppModule {}

We have imported our ShrinkHeader class and have also added it to the declarations array - this will allow us have access to it globally in our app.

Open the shrink-header.ts file and modify it to reflect the folowing:

import { Directive, ElementRef, Renderer } from '@angular/core';

@Directive({
  selector: '[shrink-header]',
  host: {
    '(ionScroll)': 'onContentScroll($event)'
  }
})
export class ShrinkHeader {

  header: any;
  headerHeight: any;
  translateAmt: any;
  
  constructor(public element: ElementRef, public renderer: Renderer) {

  }

  ngAfterViewInit() {      
    this.header = document.getElementsByTagName("ion-header")[0];
    this.headerHeight = this.header.clientHeight;
  }
 
  onContentScroll(ev) {
     ev.domWrite(() => {
            this.updateHeader(ev);
        });   
  }

  updateHeader(ev) {

    if (ev.scrollTop >= 0) {
      this.translateAmt = -ev.scrollTop / 4;
      
    } else {
       this.translateAmt =ev.scrollTop / 4;
    }

    this.renderer.setElementStyle(this.header, 'webkitTransform', 'translate3d(0,' + this.translateAmt + 'px,0)');

  }


}
Notice that the above code is self explanatory. The shrink-header attribute allows us to add the directive to an element - for us it will be shrink-header. Thost property does is listen for scroll event from the parent component, in this case, it listen for the ionScroll event, and when we detect it we will trigger the onContentScroll function in our directive. Now to use this directive on our header we will simple add the attribute to the ion-content, we also need to add fulscreen directive like so:


There you go! Do you think this can be done better? Your comments and suggestions are welcome. As usual here is the link for the full source code.

No comments:

Powered by Blogger.