ionic-framework: [4.0.0-rc.2] ion-slides do not resize after screen orientation changes in iOS

Bug Report

Ionic version: [x] 4.x

Current behavior: [4.0.0-rc.2] ion-slides do not resize after screen orientation changes in iOS

Expected behavior: ion-slides should resize when orientation changes in iOS

Steps to reproduce:

  1. Create a new ionic 4 app and add 3 or 4 slides. Or take ionic-conference-app and upgrade to 4.0.0-rc.2
  2. Build project for iOS
  3. Install on device or run in simulator and change orientation

Ionic info:

Ionic:

   ionic (Ionic CLI)             : 4.7.1 (C:\Users\gigoc\AppData\Roaming\npm\node_modules\ionic)
   Ionic Framework               : @ionic/angular 4.0.0-rc.1
   @angular-devkit/build-angular : 0.12.1
   @angular-devkit/schematics    : 7.1.4
   @angular/cli                  : 7.1.4
   @ionic/angular-toolkit        : 1.2.2

Cordova:

   cordova (Cordova CLI) : not installed
   Cordova Platforms     : not available
   Cordova Plugins       : not available

System:

   NodeJS : v8.11.3 (C:\Program Files\nodejs\node.exe)
   npm    : 6.5.0
   OS     : Windows 10

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 7
  • Comments: 19 (6 by maintainers)

Most upvoted comments

My recipe:

Template:

<ion-slides #slides>
...
</ion-slides>

Class:

  ...
  @ViewChild('slides') slides;
  ...
  @HostListener('window:resize')
  onResize() {
    setTimeout(() => this.slides.update(), 100);
  }

I’m using setTimeout() because I’m using <ion-split-pane> and there can be one more resize of the <ion-content> after the browser window resize. And listen to ionSplitPaneVisible makes everything much more complicated. But if you are not using additional elements affecting component size, you can easily drop the setTimeout.

But still — it’ll be better if the component listens to it’s size changes internally.

HTH

Having same issue, this bug is very old, no fix so far?

Please have a look in my linked post.

I’m trying desperately to figure out what could be wrong. I think it has to do with how swiper.bundle.js does device platform detection. This doesn’t seem to be handed off to capacitor’s device plugin, cordova’s device.platform or @ionic/angular’s platform for that matter, but has it’s own window.navigator.platform and window.navigator.useragent script to check the correct device platform.

I’m guessing this is where some iOS devices aren’t recognized and therefore the orientationchange event is not added to the swiper.

I could be wrong here. Let me know if I’m aiming in the right direction.

Ofcourse you could simply manually call slider.update() but that doesn’t seem like a proper fix. More like a workaround.

EDIT: Someone else also mentioned that the following css in globals.scss would also fix the issue as a workaround:

.swiper-slide-active {
width: 100% !important;
}

haven’t tried this yet though.

My solution…

npm i angular-resize-event

CSS:

ion-slide {
    width: 100% !important;
}

HTML:

<ion-slides #slider>
    <ion-slide (resized)="slider.update()">One</ion-slide>
    <ion-slide (resized)="slider.update()">Two</ion-slide>
    <ion-slide (resized)="slider.update()">Three</ion-slide>
</ion-slides>

I have this problem also with ionic 4.6. The workaround does not work on every time in my case. Sometimes the problem comes back and sometimes it can resolve by another orientation change. Strange and ugly

I created a directive off of @leechy’s recipe to patch slides automatically and reduce boilerplate if anyone would find this useful.

import { Directive, ElementRef, HostListener } from '@angular/core';
import { Platform } from '@ionic/angular';

@Directive({
  // tslint:disable-next-line: directive-selector
  selector: 'ion-slides',
})
export class PatchSlidesDirective {
  public get slides() {
    return this.el && this.el.nativeElement;
  }

  constructor(
    public el: ElementRef<HTMLIonSlidesElement>,
    public platform: Platform,
  ) {}

  @HostListener('window:resize')
  public onResize() {
    if (this.platform.is('ios')) {
      setTimeout(() => {
        if (this.slides) {
          this.slides.update();
        }
      }, 100);
    }
  }
}