Ionic 5 - long press gesture example

When I upgraded my project to Ionic 5 I had problems with hammerjs, so I writed this directive using GestureController, I hope is usefull for someone.

import {
    Directive,
    ElementRef,
    Input,
    AfterViewInit,
    NgZone,
    EventEmitter,
    Output
} from "@angular/core";
import { GestureController } from "@ionic/angular";

@Directive({
    selector: "[long-press]"
})
export class LongPressDirective implements AfterViewInit {

    @Output() press = new EventEmitter();
    @Input("delay") delay =  1500;
    action: any; //not stacking actions

    private longPressActive = false;

    constructor(
                    private el: ElementRef, 
                    private gestureCtrl: GestureController, 
                    private zone: NgZone
                ) {}
    
    ngAfterViewInit() {
        this.loadLongPressOnElement();
    }    

    loadLongPressOnElement() {
        const gesture = this.gestureCtrl.create({
            el: this.el.nativeElement,
            threshold: 0,
            gestureName: 'long-press',          
            onStart: ev => {                                       
                this.longPressActive = true;
                this.longPressAction();
            },
            onEnd: ev => {                
                this.longPressActive = false;
            }
        });
        gesture.enable(true);
    }
    
    private longPressAction() {
        if (this.action) {
            clearInterval(this.action);
        }
        this.action = setTimeout(() => {
            this.zone.run(() => {
                if (this.longPressActive === true) {
                    this.longPressActive = false;
                    this.press.emit();
                }
            });
        }, this.delay);
    }
}
<ion-button long-press (press)="yourAction()"></ion-button>
5 Likes

In Angular 9, we can simply do like below.

In Angular 9 it was decided that the implementation of Hammerjs was optional, so now we have to import the HammerModule from @angular/platform-browser .

Solution

Add the HammerModule import from @angular/platform-browser and add it to our @NgModule imports in the app.module.ts

import { BrowserModule, HammerGestureConfig, HammerModule, HAMMER_GESTURE_CONFIG} from '@angular/platform-browser';

// custom configuration Hammerjs
@Injectable()
export class HammerConfig extends HammerGestureConfig {
  overrides = <any> {
      // I will only use the swap gesture so 
      // I will deactivate the others to avoid overlaps
      'pinch': { enable: false },
      'rotate': { enable: false }
  }
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    HammerModule,
    .
    .
    .
  ],
  providers: [{provide: LocationStrategy, useClass: PathLocationStrategy},{
    provide: HAMMER_GESTURE_CONFIG,
    useClass: HammerConfig
  }],
1 Like