Igor
Igor

Reputation: 836

Router navigate on Ionic with animation blinking on ios using angular animations

I am setting page transitions between two pages on Ionic (v4) with @angular/animations and it all works great on chrome but not on safari.

On a simple app only with two pages (eagerly loaded) I still have the problem, independent of the property that I try to animate. The blinking only goes away if I create an empty animation, but it is not the goal. Also, I am using eager loading.

animations.ts

 export const fadeIn =
    trigger('fadeIn', [
      state('entering', style({ //styles to be transitioned
        opacity: 1,

      })),
      transition("* => entering", [ //this styles will enter before the animation starts
          style({
            opacity: 0,
            display: block
          }),
          animate('500ms')
      ]),

      state('leaving', style({  //this styles will enter when the animation ends
        opacity: 0,
        display: none
      })),
      transition("* => leaving", [ //styles to be transitioned
        animate('220ms', style({
          opacity: 0,
        }))
      ]),

page1.ts

... 
anim = ''
import { fadeIn } from '../animations/animations'
import { Router } from '@angular/router'
...
@Component({
  selector: 'page-1',
  templateUrl: './page1.html',
  styleUrls: ['./page1.scss'],
  animations: [ fadeIn ]
})

constructor(private router: Router){ }

ionViewWillEnter(){
  this.anim = 'entering'
}

nextPage(){
  this.router.navigate(['/page2'])
}

page2.ts

... 
import { fadeIn } from '../animations/animations'
import { Router } from '@angular/router'
...
anim = ''
@Component({
  selector: 'page-2',
  templateUrl: './page2.html',
  styleUrls: ['./page2.scss'],
  animations: [ fadeIn ]
})

constructor(private router: Router){ }

ionViewWillEnter(){
  this.anim = 'entering'
}

previousPage(){
  this.anim = 'leaving'
  setTimeout(() => {
    this.router.navigate(['/page1'])
  }, 200) //220 is the actual time to the transition end, but 200 to make sure that the blinking is not by an 'empty animation state'
}

page1.html

<ion-content [@fadeIn]='anim'>
  <h1> This is the first page!
</ion-content>

page2.html

<ion-content [@fadeIn]='anim'>
  <h1> This is the second page!
</ion-content>

page1.scss and page2.scss

ion-content{
  display: none;
  opacity: 0;
}

global.scss

@import "~@ionic/angular/css/core.css";
html > body > app-root > ion-app > ion-router-outlet > .ion-page-hidden {
  display: flex !important;
}
...

To illustrate the issue better I recorded it in slow motion and uploaded to Giphy

I expected the same result that I had on chrome on safari, which is the use of this animation structure without blinking between pages

Upvotes: 4

Views: 7797

Answers (1)

sebaferreras
sebaferreras

Reputation: 44659

I'll add this answer since it's a bit long to be a comment. As we discussed in the comments, the issue is because your animation is conflicting with the default iOS page transition animation

The recommended way to fix this issue would be to create your own page transition animation as you can see in this answer. Doing that would apply your custom animation overriding the default "animation" of all ion-nav and ion-router-outlet across the whole application.

If for some reason you just want to use Angular animations on each and every page - like you're doing in your code by using something like

<ion-content [@fadeIn]='anim'> 
  ...
</ion-content>

you can disable Ionic's default page transition animations via the Config:

animated: boolean | If true, Ionic will enable all animations and transitions across the app.

@NgModule({
  // ...
  imports: [
    // ...
    IonicModule.forRoot({
      animated: false
    }),
  ],
  //...

Upvotes: 1

Related Questions