Skip to content

bug: ion-slides regression in modals (unusable after 4.11.0) #19638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
omardoma opened this issue Oct 11, 2019 · 39 comments
Closed

bug: ion-slides regression in modals (unusable after 4.11.0) #19638

omardoma opened this issue Oct 11, 2019 · 39 comments
Labels
package: core @ionic/core package type: bug a confirmed bug report

Comments

@omardoma
Copy link

Bug Report

Ionic version:

4.11.0

Current behavior:
ion-slides now behaves strangely when placed in modals after v4.11.0, touch events aren't correctly handled and scrolling is not working, as well as layout is stretched with incorrect dimensions calculation.

v4.10.3 is working correctly.

Expected behavior:
It should work as before

Steps to reproduce:
Put an ion-slides with 2 or 3 photos in a modal page and present it, try to drag left or right, you will get stuck between photos.

Other information:

Ionic info:

Ionic:

   Ionic CLI                     : 5.4.2 (/usr/local/lib/node_modules/ionic)
   Ionic Framework               : @ionic/angular 4.11.0
   @angular-devkit/build-angular : 0.801.3
   @angular-devkit/schematics    : 8.1.3
   @angular/cli                  : 8.1.3
   @ionic/angular-toolkit        : 2.0.0

Cordova:

   Cordova CLI       : 9.0.0 (cordova-lib@9.0.1)
   Cordova Platforms : android 8.1.0
   Cordova Plugins   : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 4.1.2, (and 12 other plugins)

Utility:

   cordova-res : 0.6.0 (update available: 0.8.0)
   native-run  : 0.2.8 

System:

   Android SDK Tools : 26.1.1 (/Users/omardoma/Library/Android/sdk)
   ios-deploy        : 1.9.4
   ios-sim           : 8.0.2
   NodeJS            : v10.16.3 (/usr/local/Cellar/node@10/10.16.3/bin/node)
   npm               : 6.9.0
   OS                : macOS Mojave
   Xcode             : Xcode 11.1 Build version 11A1027
@ionitron-bot ionitron-bot bot added the triage label Oct 11, 2019
@liamdebeasi
Copy link
Contributor

Thanks for the issue. Can you provide a repo with the code required to reproduce this issue? The 4.11.0 release just had Ionic React changes, so nothing in your Ionic Angular app should be different.

@liamdebeasi liamdebeasi added the needs: reply the issue needs a response from the user label Oct 11, 2019
@ionitron-bot ionitron-bot bot removed the triage label Oct 11, 2019
@omardoma
Copy link
Author

Sorry for the late reply, I have prepared a StackBlitz demo with my current code: https://stackblitz.com/edit/ionic-v4-slides-modal-bug

However what's weird is that the bug happens non-deterministically, sometimes it happens, sometimes it doesn't, If I had to make a guess, then I would say something is blocking the slides from loading and firing the ionSlidesDidLoad event, that's why the swiping functionality and the layout is messed up.

I will investigate further and post my findings, till then please let me know if there is anything else I can help with in debugging it.

@ionitron-bot ionitron-bot bot added triage and removed needs: reply the issue needs a response from the user labels Oct 13, 2019
@liamdebeasi
Copy link
Contributor

Thanks for the follow up. I am unable to reproduce this issue using the repo you provided. Is this happening on a particular platform (iOS vs Android)?

@liamdebeasi liamdebeasi added the needs: reply the issue needs a response from the user label Oct 18, 2019
@ionitron-bot ionitron-bot bot removed the triage label Oct 18, 2019
@omardoma
Copy link
Author

Well it happens on all platforms (Browser, iOS & Android), basically what happens is, sliding becomes very glitchy, and the slides size becomes very expanded.

I believe a new issue #19641 refers to the same problem happening on React.

@ionitron-bot ionitron-bot bot added triage and removed needs: reply the issue needs a response from the user labels Oct 22, 2019
@liamdebeasi
Copy link
Contributor

Are there any particular steps to reproduce that I should be following? I am still unable to reproduce the issue using the StackBlitz.

@liamdebeasi liamdebeasi added the needs: reply the issue needs a response from the user label Oct 22, 2019
@ionitron-bot ionitron-bot bot removed the triage label Oct 22, 2019
@SimonGolms
Copy link

I can confirm the bug with the StackBlitz example as I am also affected by the linked issue for the react package.

Unfortunately, the error really occurs randomly and cannot really be reproduced . You can try to swipe back and forward several times with e.g. pressed mouse button, close modal and open it again and redo some swiping. Repeat the process multiple times until the bug appears.

Example where it happens after the first try:
23-10-_2019_14-28-45

@ionitron-bot ionitron-bot bot added triage and removed needs: reply the issue needs a response from the user labels Oct 23, 2019
@omardoma
Copy link
Author

Thank you @SimonGolms for taking the time to illustrate the bug, @liamdebeasi this is indeed what is happening, and as I said its very random, however it happens quite a lot, its actually the issue that is holding me back from upgrading past v4.10.3, as my app is heavily relying on slides as it contains a lot of media.

If there is anything we can do to help you debug it more, please let us know!

@omardoma
Copy link
Author

omardoma commented Oct 23, 2019

One thing to note is that the bug can be fixed whenever it occurs by simply triggering a window resize

@marpstar
Copy link
Contributor

We're seeing this issue as well. Oddly if we switch our tsconfig's target to es5 instead of es2015 it seems to work consistently.

@omardoma
Copy link
Author

@marpstar That's really weird. In my case, I can't really change the target to es5 because I am using Angular 8 and its differential loading, so doing so will disable it.

@marpstar
Copy link
Contributor

@omardoma I agree that switching back to ES5 isn’t ideal. I’d like to see this fixed but thought the ES5 tidbit was worth mentioning for anyone who tries to fix.

@omardoma
Copy link
Author

omardoma commented Oct 24, 2019

@marpstar Yeah definitely, thanks a lot for mentioning that, will fallback to it if the issue wasn't fixed quickly!

@omardoma
Copy link
Author

@liamdebeasi Any update on this issue, please? We really want to update our Ionic version to the latest to get some bug fixes we need, but this issue is holding us back

@SimonGolms
Copy link

SimonGolms commented Oct 30, 2019

One thing to note is that the bug can be fixed whenever it occurs by simply triggering a window resize

Good hint. I was able to fix it with the following exemplary workaround for my use case.

// slides-modal.component.html
...
<ion-content>
  <ion-slides #sliderRef>
    <ion-slide>
       ...
    </ion-slide>
  </ion-slides>
</ion-content>
...
// slides-modal.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { ModalController, IonSlides } from '@ionic/angular';

@Component({
  selector: 'app-slides-modal',
  templateUrl: './slides-modal.component.html',
  styleUrls: ['./slides-modal.component.scss']
})
export class SlidesModalComponent implements OnInit {

  @ViewChild('sliderRef', { static: true }) protected slides: IonSlides;

  constructor(private modalController: ModalController) {}

  ngOnInit() {
    this.slides.update();
  }
}

Edit: In case this workaround don't work, check this one.

@liamdebeasi liamdebeasi added the type: bug a confirmed bug report label Oct 30, 2019
@ionitron-bot ionitron-bot bot removed the triage label Oct 30, 2019
@ctcampbell
Copy link

FWIW that workaround doesn't work for me.

@ctcampbell
Copy link

Any progress being made on this?

@netsesame2
Copy link

netsesame2 commented Dec 4, 2019

My issue is slides will not swipe in a modal when it is first opened. Open the modal again, the slides works.

Following the above suggest, I solved the issue simply by adding a .update() call:

slides.update();

Don't know why.

@bohdanbirdie
Copy link

bohdanbirdie commented Dec 4, 2019

@netsesame2 thanks for the hint, looks like it worked for me

+1 to this issue tho
I'm having this on React. Doesn't work on iOS but does in browser

@tiagomsmagalhaes
Copy link

I have found this issue without the modal use case, just simple routing back and forth.

After trying ChangeDetectorRef or @SimonGolms solution without success I have added a ngIf to my slider-wrapper and set the variable to true on AfterContentCheckedand it worked without hiccups.

Haven't tried on previous hooks.

@ebk46
Copy link

ebk46 commented Jan 3, 2020

I'm having this issue as well. I'm using React 4.11.7, and in addition to the sliding problem, I also have a problem where sometimes the slide simply will not work at all. I can swipe and it emits the onIonSlideNextStart / ...PrevStart events but the slide itself does not change.

@ctcampbell
Copy link

Any chance of this getting fixed?

@ctcampbell

This comment has been minimized.

@liamdebeasi
Copy link
Contributor

liamdebeasi commented Jan 13, 2020

Hi,

I am hiding your comment as it is off topic and not constructive to getting this issue resolved. I will try to take a look at this issue this week.

We have acknowledged this is an issue here. We are looking into a resolution; however, since it appears randomly it is a bit tricky to resolve. Additionally, a few users on this thread have provided temporary workarounds. I will post another update here when I have more information to share.

Thanks!

@SimonGolms
Copy link

SimonGolms commented Feb 11, 2020

Hi @liamdebeasi, any news regarding this bug?
I noticed that after calling modal.present() several times with a <ion-slides> component, the nested <ion-slide> elements are not handled correctly. In case this bug appears, swiper.length() returns 0. During debugging I also noticed that the bug occurs more often when I use <ion-content fullscreen="true"> in my component.

While my first workaround unfortunately didn't really work, I want to share another possible workaround, were I was not able to reproduce the bug after intensive testing.

// slides-modal.component.html
...
<ion-content>
  <ion-slides #sliderRef></ion-slides>
</ion-content>
...
// slides-modal.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { ModalController, IonSlides } from '@ionic/angular';

@Component({
  selector: 'app-slides-modal',
  templateUrl: './slides-modal.component.html',
  styleUrls: ['./slides-modal.component.scss']
})
export class SlidesModalComponent implements OnInit {

  @ViewChild('sliderRef', { static: true }) protected slides: IonSlides;

  src = './assets/img.png'
  constructor(private modalController: ModalController) {}

  async ngOnInit() {
    const swiper = await this.slides.getSwiper();
    swiper.appendSlide(`<ion-slide><img src="${this.src}"/></ion-slide>`);
    ...
  }
}

@NikolaDeveloper
Copy link

Is there any workaround for react?

@FranzSw
Copy link

FranzSw commented Mar 2, 2020

Would love to hear some news on this.

@NikolaDeveloper Here's a one line fix / workaround for React:

// ...
<IonSlides onIonSlidesDidLoad={function(this: any){this.update()}}>
//...

It basically just calls update on IonSlides after loading. It's nice because it doesn't need any ref or additional variable.

@robsonos
Copy link

robsonos commented Apr 20, 2020

Fixed it with the ionViewDidEnter hook instead:

ionViewDidEnter () {
  this.slides.update();
}

@kheftel
Copy link

kheftel commented Aug 9, 2020

For anyone that's interested, with @ionic/angular 5.2.1, I had to change the workaround to the following for pagination to work on the second load of the modal. Looks like you have to use ElementRef<IonSlides> instead of using IonSlides directly with ViewChild. Took me a couple days to figure this out so I'm posting in case anyone else is stuck on it.

template:

<ion-slides pager="true" #sliderRef>

component:

@Component({
  selector: 'app-slidesmodal',
  templateUrl: 'slidesmodal.page.html',
  styleUrls: ['slidesmodal.page.scss'],
})
export class SlidesModalPage {
  @Input() modalController: ModalController
  @ViewChild('sliderRef') slides: ElementRef<IonSlides>;

  constructor(
  ) {}

  ionViewDidEnter() {
    this.slides.nativeElement.update();
  }
}

ionic info:

Ionic:

   Ionic CLI                     : 6.10.1
   Ionic Framework               : @ionic/angular 5.2.1
   @angular-devkit/build-angular : 0.901.8
   @angular-devkit/schematics    : 9.1.7
   @angular/cli                  : 9.1.8
   @ionic/angular-toolkit        : 2.2.0

Capacitor:

   Capacitor CLI   : 2.2.1
   @capacitor/core : 2.3.0

Utility:

   cordova-res (update available: 0.15.1) : 0.14.0
   native-run                             : 1.0.0

System:

   NodeJS : v12.17.0
   npm    : 6.14.5
   OS     : macOS Catalina

@dimzeta
Copy link

dimzeta commented Aug 12, 2020

@kheftel If you have only one ion-slides in your component, you can do that to get IonSlides without ElementRef :

@ViewChild(IonSlides) slides: IonSlides;

ionViewWillEnter() {
	this.slides.update()
}

@kheftel
Copy link

kheftel commented Aug 12, 2020

@kheftel If you have only one ion-slides in your component, you can do that to get IonSlides without ElementRef :

@ViewChild(IonSlides) slides: IonSlides;

ionViewWillEnter() {
	this.slides.update()
}

I tried that first, but, sadly it didn't work and my slides variable was still an ElementRef, and iirc its nativeElement didn't have an update function. At any rate this.slides.update() was not a function.

@rastafan
Copy link

rastafan commented Sep 28, 2020

We stumpled upon something like this these days, using Ionic+Angular. Rendering an ion-slides inside a modal causes the ion-slides component to be rendered wrong.

More specifically, the slides are rendered "centered" inside the ion-slides. We have three slides, so we see the second one in the screen (slightly misplaced), and inspecting the dom the first slide is on the left, outside the screen.

We are sliding the slides programamtically using buttons, and they work, but they are rendered completely out of place.

The slides.update trick did not solve the issue.

Hiding the slides with *ngIf and showing them after ionViewDidEnter rendered them correctly, but they still flash rendered bad before being rendered good, which is quite ugly.

This seems to be related to the slides being rendered while outside the view or in a moment where they can not access the correct view size (just as hypotesis, i'm not completely sure about this).

EDIT: We found the beforementioned *ngIf workaround HERE

@ThierryLib
Copy link

I have got a similar problem with Ionic-Angular, only on Safari. My iOS App is not affected.
When launching programmatically my component with a slider in a modal, it opens properly and after a fraction of a second it moves by half the size of the modal and stays between two slides.
Example here: https://app.latourneedesproducteurs.com/drivefermierdesaintvictor
Select a product and click on "Réserver" to open the modal.

I tried the *ngIf and the slides.update(), but nothing worked for me.
Chrome, Firefox and mobile apps are ok.

It's pretty ambarrassing.

@dheimoz
Copy link

dheimoz commented Mar 1, 2021

In case you are looking for this solution applied to Vue 3, here it is. First your ion-slides component needs a ref. For instance "slides"

<ion-content fullscreen class="ion-padding" scroll-y="false">
    <ion-slides ref="slides">
      <ion-slide>
        <h1>Slide 1</h1>
      </ion-slide>
      <ion-slide>
        <h1>Slide 2</h1>
      </ion-slide>
      <ion-slide>
        <h1>Slide 3</h1>
      </ion-slide>
    </ion-slides>
  </ion-content>

Then in your setup

setup() {
    const slides = ref();
    onMounted(() => {
      slides.value.$el.update();
    });
    return { slides };
  },

This way, when the Modal is present and mounted the slides component is updated.

Hope this helps. I believe there is no other way to make it work because it is not a problem with the IonicFramework but the integration with Swyper.js

@liamdebeasi
Copy link
Contributor

Hi everyone,

This was resolved via #24257 and a fix will be available in an upcoming release of Ionic. This fix will be available in both Ionic 5 and Ionic 6. Thanks!

@ionitron-bot
Copy link

ionitron-bot bot commented Jan 1, 2022

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.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Jan 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
package: core @ionic/core package type: bug a confirmed bug report
Projects
None yet
Development

No branches or pull requests