ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.02k stars 13.51k forks source link

bug: On iOS devices, Infinite Scroll jumps to top when ionInfinite event is fired #20148

Closed bennyt2 closed 3 years ago

bennyt2 commented 4 years ago

Bug Report

Ionic version:

[x] 4.x

Current behavior:

On iOS devices, the screen jumps to the top of the list when items are added to a list via the infinite scroll component.

This is not a problem on the web (Chrome or Safari) or on Android devices.

iosInfiniteScrollIssue

Expected behavior:

The screen scroll should not be affected by adding items to a list. The user should see new posts appear and continue scrolling as normal.

Steps to reproduce:

  1. Build the app in Xcode
  2. Run on a device
  3. Start scrolling down. Once you hit Post 5, you'll be sent to the top of the screen (Post 1).

Related code:

The repo is at https://github.com/bennyt2/ionic-infinite-scroll-test. Here are the two relevant files:

src/app/home/home.page.html: HTML that uses ion-infinite-scroll

<ion-content>
  <ng-container *ngFor="let post of posts;let i = index">
    <div class="post post-{{post % 2}}">Post {{post}}</div>
  </ng-container>

  <div class="no-posts-yet" *ngIf="posts.length === 0">No posts yet...</div>
  <div class="end-of-feed" *ngIf="allPostsLoaded">End of feed</div>

  <ion-infinite-scroll class="infinite-scroll" threshold="300px" (ionInfinite)="getMorePosts($event)">
    <ion-infinite-scroll-content loadingSpinner="circles" loadingText="Loading more posts...">
    </ion-infinite-scroll-content>
  </ion-infinite-scroll>

</ion-content>

src/app/home/home.page.ts: Component that handles post retrieval and the ionInfinite event

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-infinite-scroll-test',
  templateUrl: './infinite-scroll-test.page.html',
  styleUrls: ['./infinite-scroll-test.page.scss'],
})
export class InfiniteScrollTestPage implements OnInit {

  posts: number[] = [];
  maxPosts: number = 100;
  step: number = 5;
  loadedPosts: number = 0;
  allPostsLoaded: boolean = false;

  constructor() {
  }

  ngOnInit() {
    this.addPosts(5);
  }

  addPosts(number: number) {
    for (let i = 0; i < number; i++) {
      this.posts.push(this.posts.length + 1);
      this.loadedPosts = this.posts.length + 1;
    }
  }

  getMorePosts(event) {
    setTimeout(() => {
      this.addPosts(5);
      event.target.complete();

      // App logic to determine if all data is loaded
      // and disable the infinite scroll
      if (this.loadedPosts > this.maxPosts) {
        event.target.disabled = true;
        this.allPostsLoaded = true;
      }
    }, 500)
  }
}

Ionic info:

Ionic:

   Ionic CLI                     : 5.4.1 (/home/spikefalcontwo/.nvm/versions/node/v10.15.3/lib/node_modules/ionic)
   Ionic Framework               : @ionic/angular 4.11.7
   @angular-devkit/build-angular : 0.801.3
   @angular-devkit/schematics    : 8.1.3
   @angular/cli                  : 8.1.3
   @ionic/angular-toolkit        : 2.1.1

Capacitor:

   Capacitor CLI   : 1.4.0
   @capacitor/core : 1.4.0

Utility:

   cordova-res : not installed
   native-run  : not installed

System:

   NodeJS : v10.15.3 (/home/spikefalcontwo/.nvm/versions/node/v10.15.3/bin/node)
   npm    : 6.11.3
   OS     : Linux 5.0
bennyt2 commented 4 years ago

Any thoughts? This is still a problem.

wolzenbug commented 4 years ago

I'm also encountering this problem. The only thing I did was updating "@capacitor/ios" and "@capacitor/core" from version: 1.2.1 to: 1.4.0.

Edit: Fixed my problem by restructuring the template, because I was using nested <ion-content> (bad idea).

domvanrob commented 4 years ago

Did you ever get around to finding a solution yourself? I've currently got a similar situation where as it doesn't occur on the web or android, it does on iOS.

Currently got a dirty workaround which saves the scroll position from the onScroll($event) on my ion-content then with a timeout forces the window to be scrolled down to the last known position. What makes it even uglier is the fact that you actually see the jump up - then down happen..

wolzenbug commented 4 years ago

@robbievandam I'm not sure if your question was addressed to me, but the only thing I can say is: The bug disappeared as soon as I removed an <ion-content> which was a (not direct) children of another <ion-content>. So you could check if you also accidentally nested ion-contents. In case you already did and the bug is still present - I'm sorry, I wish I could give more information.

ZeroSkill830 commented 3 years ago

@bennyt2 Did you managed to resolve the issue?

bennyt2 commented 3 years ago

@ZeroSkill830: @wolzenbug's solution worked for me.

ZeroSkill830 commented 3 years ago

@bennyt2 I have only one ion-content but the issue is still here. Any ideas?

bennyt2 commented 3 years ago

Only other thing I can think of is to make sure you're on the latest Ionic version.

On Wed, Apr 21, 2021 at 9:45 AM ZeroSkill830 @.***> wrote:

@bennyt2 https://github.com/bennyt2 I have only one ion-content but the issue is still here. Any ideas?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ionic-team/ionic-framework/issues/20148#issuecomment-824073186, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABNBWARBKBR5WDGJ3ISYTY3TJ3JG3ANCNFSM4KDLOXXQ .

-- Ben Thomas Director of Live Results, Athletic.net Lead Developer, AthleticLIVE @.***

ZeroSkill830 commented 3 years ago

Only other thing I can think of is to make sure you're on the latest Ionic version. On Wed, Apr 21, 2021 at 9:45 AM ZeroSkill830 @.> wrote: @bennyt2 https://github.com/bennyt2 I have only one ion-content but the issue is still here. Any ideas? — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#20148 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABNBWARBKBR5WDGJ3ISYTY3TJ3JG3ANCNFSM4KDLOXXQ . -- Ben Thomas Director of Live Results, Athletic.net Lead Developer, AthleticLIVE @.

@ZeroSkill830: @wolzenbug's solution worked for me. I see that in your repo you had just one ion-content. What ion-content did you removed?

ionitron-bot[bot] commented 3 years ago

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.