Ionic android modal not over previous modal on top view năm 2024

When we launch a modal in an Ionic application, an animation is used to provide a smooth transition as it appears on the screen. The default animation for iOS and Android causes the modal to slide up from the bottom – the effect is more pronounced on iOS, but the animation is similar on both platforms. This animation is perfectly suited to the platforms it runs on and most people will just stick with the default animation (there is no specific reason not to).

However, it is possible to supply your own custom transition animations if you wish. In this tutorial, we are going to look at how we can modify the default animations that Ionic supplies to create our own open and close animations for modals.

We will be creating some custom animations that look like this:

Ionic android modal not over previous modal on top view năm 2024
Ionic android modal not over previous modal on top view năm 2024

Before We Get Started

Last updated for Ionic 4, beta.13

This is an advanced tutorial that assumes you already have a decent working knowledge of the Ionic framework. If you require more introductory level content on Ionic I would recommend checking out my book or the Ionic tutorials on my website.

1. Supplying an Animation to a Modal

The way in which we typically create a modal looks something like this:

this.modalCtrl
  .create({
    component: ModalPage,
  })
  .then((modal) => {
    modal.present();
  });

However, there are many more options that we can supply when creating this modal which are outlined here. Those options include an option to specify an

this.modalCtrl
  .create({
    component: ModalPage,
    enterAnimation: myEnterAnimation,
    leaveAnimation: myLeaveAnimation,
  })
  .then((modal) => {
    modal.present();
  });

2 and a

this.modalCtrl
  .create({
    component: ModalPage,
    enterAnimation: myEnterAnimation,
    leaveAnimation: myLeaveAnimation,
  })
  .then((modal) => {
    modal.present();
  });

3 like this:

this.modalCtrl
  .create({
    component: ModalPage,
    enterAnimation: myEnterAnimation,
    leaveAnimation: myLeaveAnimation,
  })
  .then((modal) => {
    modal.present();
  });

All we need to do is create those

this.modalCtrl
  .create({
    component: ModalPage,
    enterAnimation: myEnterAnimation,
    leaveAnimation: myLeaveAnimation,
  })
  .then((modal) => {
    modal.present();
  });

4 and

this.modalCtrl
  .create({
    component: ModalPage,
    enterAnimation: myEnterAnimation,
    leaveAnimation: myLeaveAnimation,
  })
  .then((modal) => {
    modal.present();
  });

5 animations. That is what we will be focusing on in the next step.

2. Creating a Custom Transition Animation

Creating the transition animation isn’t exactly an easy task, fortunately, the Ionic team have already done most of the work for us. We can use the existing animations that they have created for the default transitions and build our solution on top of that.

You can find those animations here. Our solution is going to look slightly different to this, but most of the code will remain the same. We are going to create new files for our animations, and those files are going to

this.modalCtrl
  .create({
    component: ModalPage,
    enterAnimation: myEnterAnimation,
    leaveAnimation: myLeaveAnimation,
  })
  .then((modal) => {
    modal.present();
  });

6 the animation we want to use.

Create a new file at src/app/animations/enter.ts and add the following:

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

We have pretty much just copy and pasted the code from Ionic directly in here, except that we are now importing

this.modalCtrl
  .create({
    component: ModalPage,
    enterAnimation: myEnterAnimation,
    leaveAnimation: myLeaveAnimation,
  })
  .then((modal) => {
    modal.present();
  });

7 from

this.modalCtrl
  .create({
    component: ModalPage,
    enterAnimation: myEnterAnimation,
    leaveAnimation: myLeaveAnimation,
  })
  .then((modal) => {
    modal.present();
  });

8.

This code might look somewhat intimidating, but there are only a few things you need to know for basic animations. The most important part is the

this.modalCtrl
  .create({
    component: ModalPage,
    enterAnimation: myEnterAnimation,
    leaveAnimation: myLeaveAnimation,
  })
  .then((modal) => {
    modal.present();
  });

9:

wrapperAnimation
  .beforeStyles({ opacity: 1 })
  .fromTo('translateY', '100%', '0%');

The

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

0 method animates the styles on the modal

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

1 one thing

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

2 another thing. In this case, the

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

3 is being animated from

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

4 (i.e. off-screen, to the bottom) to

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

5 (i.e. in the center of the screen). You can change the properties being animated here, and you can event animate multiple properties by chaining the

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

0 method:

wrapperAnimation
  .beforeStyles({ opacity: 1 })
  .fromTo('translateY', '100%', '0%')
  .fromTo('somethingelse', 'beforevalue', 'aftervalue')
  .fromTo('somethingelse', 'beforevalue', 'aftervalue');

You may also wish to modify the

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

7 to change the length of the animation of the easing function. More complex animations may require more modifications, but you should be able to do a lot with just this.

Let’s also set up the leave animation before continuing:

Create a new file at src/app/animations/leave.ts and add the following:

import { Animation } from '@ionic/core';
export function myLeaveAnimation(AnimationC: Animation, baseEl: HTMLElement): Promise {
    const baseAnimation = new AnimationC();
    const backdropAnimation = new AnimationC();
    backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
    const wrapperAnimation = new AnimationC();
    const wrapperEl = baseEl.querySelector('.modal-wrapper');
    wrapperAnimation.addElement(wrapperEl);
    const wrapperElRect = wrapperEl!.getBoundingClientRect();
    wrapperAnimation.beforeStyles({ 'opacity': 1 })
                    .fromTo('translateY', '0%', `${window.innerHeight - wrapperElRect.top}px`);
    backdropAnimation.fromTo('opacity', 0.4, 0.0);
    return Promise.resolve(baseAnimation
      .addElement(baseEl)
      .easing('ease-out')
      .duration(250)
      .add(backdropAnimation)
      .add(wrapperAnimation));
}

We could actually make use of these animations with our modal now and they would work. That’s a bit boring though because the animation is exactly the same as the default one.

Instead, we are going to create a transition animation that will slide the modal in from the left, and out through the right.

This is an easy modification to make because it is mostly the same as the original animation, just in a different direction.

Modify src/app/animations/enter.ts to reflect the following:

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateX', '-100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

Modify src/app/animations/leave.ts to reflect the following:

import { Animation } from '@ionic/core';
export function myLeaveAnimation(AnimationC: Animation, baseEl: HTMLElement): Promise {
    const baseAnimation = new AnimationC();
    const backdropAnimation = new AnimationC();
    backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
    const wrapperAnimation = new AnimationC();
    const wrapperEl = baseEl.querySelector('.modal-wrapper');
    wrapperAnimation.addElement(wrapperEl);
    const wrapperElRect = wrapperEl!.getBoundingClientRect();
    wrapperAnimation.beforeStyles({ 'opacity': 1 })
                    .fromTo('translateX', '0%', `${window.innerWidth - wrapperElRect.left}px`);
    backdropAnimation.fromTo('opacity', 0.4, 0.0);
    return Promise.resolve(baseAnimation
      .addElement(baseEl)
      .easing('ease-out')
      .duration(250)
      .add(backdropAnimation)
      .add(wrapperAnimation));
}

The original animation was modifying

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

3 to push the modal up and down, but now we are using

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

9 to push the modal left and right. It is the exact same concept, except we are animating over the horizontal plane rather than the vertical plane. Also, keep in mind that we have changed the

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

2 value in the leave animation to use the

wrapperAnimation
  .beforeStyles({ opacity: 1 })
  .fromTo('translateY', '100%', '0%');

1 and

wrapperAnimation
  .beforeStyles({ opacity: 1 })
  .fromTo('translateY', '100%', '0%');

2 values instead of

wrapperAnimation
  .beforeStyles({ opacity: 1 })
  .fromTo('translateY', '100%', '0%');

3 and

wrapperAnimation
  .beforeStyles({ opacity: 1 })
  .fromTo('translateY', '100%', '0%');

4.

3. Using a Custom Transition for a Modal

We have our custom animation, now we just need to use it. Fortunately, this is extremely straight-forward. Just import the animation into the page where you are creating the modal:

import { myEnterAnimation } from '../animations/enter';
import { myLeaveAnimation } from '../animations/leave';

and then supply those animations when creating the modal:

this.modalCtrl
  .create({
    component: ModalPage,
    enterAnimation: myEnterAnimation,
    leaveAnimation: myLeaveAnimation,
  })
  .then((modal) => {
    modal.present();
  });

4. Getting Fancier

The animation we created was pretty simple, we mostly kept the code exactly the same but we changed the direction. Now we are going to create something a little more custom:

Ionic android modal not over previous modal on top view năm 2024

Modify src/app/animations/enter.ts to reflect the following:

this.modalCtrl
  .create({
    component: ModalPage,
    enterAnimation: myEnterAnimation,
    leaveAnimation: myLeaveAnimation,
  })
  .then((modal) => {
    modal.present();
  });

0

Modify src/app/animations/leave.ts to reflect the following:

this.modalCtrl
  .create({
    component: ModalPage,
    enterAnimation: myEnterAnimation,
    leaveAnimation: myLeaveAnimation,
  })
  .then((modal) => {
    modal.present();
  });

1

Now we have an animation that will cause the modal to “pop” in and out of the screen. We have removed the

wrapperAnimation
  .beforeStyles({ opacity: 1 })
  .fromTo('translateY', '100%', '0%');

5 entirely as we don’t want the modal to be visible to begin with. Instead of supplying an initial opacity, we supply a second

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

0 that will animate the opacity of the modal from

wrapperAnimation
  .beforeStyles({ opacity: 1 })
  .fromTo('translateY', '100%', '0%');

7 to

wrapperAnimation
  .beforeStyles({ opacity: 1 })
  .fromTo('translateY', '100%', '0%');

8 over the course of the animation.

Rather than moving the modal on and off the screen with

wrapperAnimation
  .beforeStyles({ opacity: 1 })
  .fromTo('translateY', '100%', '0%');

9, we are now using a

wrapperAnimation
  .beforeStyles({ opacity: 1 })
  .fromTo('translateY', '100%', '0%')
  .fromTo('somethingelse', 'beforevalue', 'aftervalue')
  .fromTo('somethingelse', 'beforevalue', 'aftervalue');

0 transform to shrink and grow the modal. This will cause the modal to animate from a very small size to its natural size, and then from it’s natural size to a very small size as it disappears from the changing opacity. We do still need to keep the

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

9 on the enter animation as well to position the modal correctly.

We’ve also changed the

import { Animation } from '@ionic/core';
export function myEnterAnimation(
  AnimationC: Animation,
  baseEl: HTMLElement
): Promise {
  const baseAnimation = new AnimationC();
  const backdropAnimation = new AnimationC();
  backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
  const wrapperAnimation = new AnimationC();
  wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));
  wrapperAnimation
    .beforeStyles({ opacity: 1 })
    .fromTo('translateY', '100%', '0%');
  backdropAnimation.fromTo('opacity', 0.01, 0.4);
  return Promise.resolve(
    baseAnimation
      .addElement(baseEl)
      .easing('cubic-bezier(0.36,0.66,0.04,1)')
      .duration(400)
      .beforeAddClass('show-modal')
      .add(backdropAnimation)
      .add(wrapperAnimation)
  );
}

7 of the animation to be

wrapperAnimation
  .beforeStyles({ opacity: 1 })
  .fromTo('translateY', '100%', '0%')
  .fromTo('somethingelse', 'beforevalue', 'aftervalue')
  .fromTo('somethingelse', 'beforevalue', 'aftervalue');

3, which is slightly longer than the other animation.

Summary

With just a few small changes, we are able to significantly impact the way the modal is animated onto and off of the screen. It is probably not all that often that you would need to use your own custom transition animations, but for circumstances where you do, this is a rather straight-forward and powerful way to do that.

How do you show modal in Ionic?

ion-modal can be used by writing the component directly in your template. This reduces the number of handlers you need to wire up in order to present the modal. When using ion-modal with Angular, React, or Vue, the component you pass in will be destroyed when the modal is dismissed.nullion-modal: Ionic Mobile App Custom Modal API Componentionicframework.com › docs › api › modalnull

How do you dismiss a modal in Ionic 7?

Dismiss Method. After creating a modal, you can dismiss it by calling the dismiss() method on the modal controller. The onDidDismiss function can be called for performing additional actions after the modal is dismissed. Let us see step by step to learn how the modal controller works in the Ionic application.nullIonic Modal - javatpointwww.javatpoint.com › ionic-modalnull

How to pass data in ion modal?

Passing data to an Ionic modal This is as simple as calling the componentProps on our modalController create function. number: number = 3; const modal = await this. modalController. create({ component: DetailPage, componentProps: { number: this.nullIonic modals passing and receiving data - Daily Dev Tipsdaily-dev-tips.com › posts › ionic-modals-passing-and-receiving-datanull