Ionic-framework: [rc2] spinner stops in safari when angular change detected

Created on 22 Jan 2019  路  15Comments  路  Source: ionic-team/ionic-framework

Bug Report

Ionic version:


[x] 4.0 rc2

Current behavior:
In Safari (both on iOS and Mac) spinner stops spinning when data are loaded. Data are loaded from firebase + angular fire + observable. It looks like it is related with change detection in angular. Very likely it also affects other components, that are animated. I've made a video (https://drive.google.com/file/d/1dmtEEBcO3RiapbP5t0pnss7UwSGY8pQc/view?usp=sharing), that shows what is happening and you can reproduce it with the repo below. What you can't see in the video is that when safari loaded the app (spinner stopped) and you open new tab and go back the previous tab (with the app loaded) the spinner spins again.

It was working properly in rc0, I'm not sure about rc1.

My Safari version is 12.0.2 (14606.3.4).

Expected behavior:
Spinner is spinning.

Steps to reproduce:

  1. Download https://github.com/MarkChrisLevy/ionic-spinner-issue
  2. npm install && npm run start
  3. open safari and go to localhost:4200
  4. the app should load and when the data are loaded (few seconds) you should see that spinner stopped spinning.
angular

Most helpful comment

Still an issue.. Having the same problem here :-(. Someone has a workaround or sth?
angular: 7.2.15, ionic: 4.4.0

All 15 comments

Hmm, interesting. So it appears the visual glitch doesn't actually stop the animations. If you inspect the DOM, you can see the highlights of the animation still happening.

Also, it seems to only happen when the changeDetection is triggered in the same element.
This is not limited to ion-spinner, but any keyframe animations.

@mhartington Exactly! I tried with with angular 7.2.1 and 7.1.4 and no difference, so it has to be somewhere in ionic and I'm almost sure, that it didn't happen in rc0 (or I didn't notice that). Safari is killing me with those glitches...

Still an issue.. Having the same problem here :-(. Someone has a workaround or sth?
angular: 7.2.15, ionic: 4.4.0

I'm having this issue as well. Added the spinner to a page. spinner freezes as soon as page navigation transition completes.
Appreciate if someone can share a workaround.

We have the same issue. Is there a workaround?

Yup same here, after debugging, it seems that navigation between tabs aren't affected by this.

As a workaround, which I'm absolutely not happy with, I navigate to other pages from the one with animation (like spinners) like they are tabs (but not really).

EDIT

After testing my previous workaround, I was really not happy with it since it was messing up with the whole navigation stack.

Long story short I come here with a much more reliable solution, it is just a directive and you apply it on the element which has the animation, it even works with IonSpinner.

I'm not totally happy with this because it's still a workaround which has a a debounce time of _620ms_ (don't you dare asking me how or why) and I hate having to deal with this kind of crapy code... But since this issue was opened more than 6 months ago and I need a solution right now, this is the best stuff I came up with.

Hope it'll help somebody...

import { merge, of, Subject } from "rxjs";
import { IonSpinner, Platform } from "@ionic/angular";
import { NavigationEnd, Router } from "@angular/router";
import { debounceTime, filter, takeUntil, tap } from "rxjs/operators";
import { Directive, ElementRef, OnDestroy, OnInit } from "@angular/core";

/**
 * Attempt to fix animation stopping in Safari
 *
 * @see https://github.com/ionic-team/ionic/issues/17202#issuecomment-519127330
 *
 * @usage `<ion-spinner safariAnimate></ion-spinner>`
 */
@Directive({
    selector: '[safariAnimate]',
})
export class SafariAnimateDirective implements OnInit, OnDestroy {

    private destroy$ = new Subject<true>();


    constructor(
        private router: Router,
        private platform: Platform,
        private elementRef: ElementRef<HTMLElement | IonSpinner | any>,
    ) {
    }


    ngOnInit() {
        if (!this.platform.is("ios")) {
            return;
        }

        const url = this.router.routerState.snapshot.url;

        merge(
            of(true),
            this.router.events
                .pipe(filter((event) => event instanceof NavigationEnd))
                .pipe(filter((event: NavigationEnd) => event.url === url)),
        )
            .pipe(tap(() => this.pauseElement()))
            .pipe(debounceTime(620))
            .pipe(takeUntil(this.destroy$))
            .subscribe(() => this.pauseElement(false));
    }


    ngOnDestroy() {
        this.destroy$.next(true);
        this.destroy$.unsubscribe();
    }


    private pauseElement(paused = true) {
        this.elementRef.nativeElement.paused = paused;

        if (paused) {
            this.elementRef.nativeElement.style.animationPlayState = "paused";
        } else {
            this.elementRef.nativeElement.style.animationPlayState = "running";
        }
    }

}

I had this issue and in my case this what I did.

<ion-spinner name="circles"  #spinner></ion-spinner>

@ViewChild('spinner', { read: IonSpinner }) public spinner: IonSpinner;
ionViewDidEnter() {
    if (this.platform.is('ios')) {
      this.spinner.paused = true;
      setTimeout(() => {
        this.spinner.paused = false;
      }, 200);
    }
  }

It worked, at least for me.

public paused = true;

ionViewDidEnter() {
this.paused = false;
}

Still in angular 8

This works for me:

private spinner: IonSpinner;

    @ViewChild('spinner', {read: IonSpinner}) set content(content: IonSpinner) {
        if (content && !this.spinner) {
            this.spinner = content;
            this.spinner.paused = true;
            setTimeout(() => {
                this.spinner.paused = false;
            }, 200);
        }

    }

Idea: spinner is initiated, restart it.

Hi everyone,

I wanted to provide an update regarding this issue. We have determined that this is a bug in WebKit (https://bugs.webkit.org/show_bug.cgi?id=201048). Recently, this issue was fixed and released as part of the latest Safari Technology Preview (release 101 at the time of writing).

We do not have a timeline as to when the fix will become available for all users as that release schedule is controlled by Apple.

@liamdebeasi Aside from the fact that there is almost always a half-decent workaround for issues such as this.... Why is it acceptable to close this issue without making note of the issue in the docs? Because what we have now is a main component of ionic that flat out doesn't work on iOS. And your response is to just shoulder shrug and close the issue?

I realize you folks have a lot of issues to deal with... but that response is quite amateur.

We close issues here when any code that is responsible for fixing a bug has been merged (either into an Ionic repo or a 3rd party repo). In this case, code was merged into the WebKit repo that fixed this issue.

The workarounds that have been provided here should do the trick until Apple can ship this fix out. I realize the workarounds are not as ideal as having a fix right now, but we do not control WebKit's release process.

@liamdebeasi If you had encountered this issue while building the feature for its initial release, would you have released the feature?

I understand that having this unexpected behavior is frustrating, but I am not going to comment on that. I am going to lock this thread as I think the discussion regarding this issue has been resolved.

For any additional bugs or feature requests, please create a new issue. Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexbainbridge picture alexbainbridge  路  3Comments

giammaleoni picture giammaleoni  路  3Comments

alan-agius4 picture alan-agius4  路  3Comments

Nick-The-Uncharted picture Nick-The-Uncharted  路  3Comments

daveshirman picture daveshirman  路  3Comments