Skip to content

bug: ion-picker moving by its own when emulated in tablet #30299

Closed as duplicate

Description

@MikelMoli

Prerequisites

Current Behavior

When using ion-picker component to let the user choose how much time will a timer run, the ion-picker moves by its own and doesn't stay in the column option that the user has set. This happens only in tablets simulators in the browser (I don't have a tablet my own to test this).

This has been tested in Chrome and Mozilla. It doesn't seem to be an Apple thing, as in the iPhone devices it works properly.

In Mobile - iPhone 12 pro (it works OK in other mobile devices too)

Image

In tablet - iPad Pro (it happens in all the tablets)

Image

Expected Behavior

Ion-picker column does not change its values by its own in tablets as it does in mobile devices.

Steps to Reproduce

  1. Create the next HTML and TS file:

This is my component HTML:

<ion-picker class="custom-picker">
  <ion-picker-column 
    [value]="selectedHour" 
    (ionChange)="hourChanged($event)">
    <ion-picker-column-option *ngFor="let num of hourOptions" [value]="num">{{ num }}</ion-picker-column-option>
  </ion-picker-column>
  <ion-picker-column 
    [value]="selectedMinute" 
    (ionChange)="minuteChanged($event)">
    <div class="two-dots" slot="prefix">:</div>
    <ion-picker-column-option *ngFor="let num of secMinOptions" [value]="num">{{ num }}</ion-picker-column-option>
    <div class="two-dots" slot="suffix">:</div>
  </ion-picker-column>
  <ion-picker-column 
    [value]="selectedSecond" 
    (ionChange)="secondChanged($event)">
    <ion-picker-column-option *ngFor="let num of secMinOptions" [value]="num">{{ num }}</ion-picker-column-option>
  </ion-picker-column>
</ion-picker>

This is my TS file:

import { CommonModule } from '@angular/common';
import { AfterViewInit, Component, ElementRef, EventEmitter, Output, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { IonicModule, IonPicker } from '@ionic/angular';

@Component({
  selector: 'app-custom-class-length',
  standalone: true,
  imports: [IonicModule, FormsModule, CommonModule],
  templateUrl: './custom-class-length.component.html',
  styleUrls: ['./custom-class-length.component.scss'],
})
export class CustomClassLengthComponent implements AfterViewInit {
  @Output() timeChanged = new EventEmitter<string>();
  selectedHour: string = '00';
  selectedMinute: string = '00';
  selectedSecond: string = '30';
  hourOptions = Array.from({ length: 24 }, (_, i) => i.toString().padStart(2, '0'));
  secMinOptions = Array.from({ length: 60 }, (_, i) => i.toString().padStart(2, '0'));

  constructor() {}

  ngAfterViewInit(): void {
    setTimeout(() => {
      const picker = document.querySelector('ion-picker.custom-picker');
      if (picker && picker.shadowRoot) {
        const beforeEl = picker.shadowRoot.querySelector('.picker-before') as HTMLElement;
        const afterEl = picker.shadowRoot.querySelector('.picker-after') as HTMLElement;
    
        if (beforeEl) beforeEl.style.background = 'transparent';
        if (afterEl) afterEl.style.background = 'transparent';
      }

      const pickerOptions = document.querySelectorAll('ion-picker-column-option');

      pickerOptions.forEach((option) => {
        const shadowButton = option.shadowRoot?.querySelector('button');
        
        if (shadowButton) {
          shadowButton.style.height = '100%';
          shadowButton.style.lineHeight = 'unset';
        }
      });
    }, 100);
  }

  getSelectedTime() {
    return 
  }

  hourChanged(event: CustomEvent) {
    this.selectedHour = event.detail.value;
    this.emitTime();
  }

  minuteChanged(event: CustomEvent) {
    this.selectedMinute = event.detail.value;
    this.emitTime();
  }

  secondChanged(event: CustomEvent) {
    this.selectedSecond = event.detail.value;
    this.emitTime();
  }

  private emitTime() {
    let timeValue = `${this.selectedHour}:${this.selectedMinute}:${this.selectedSecond}`
    console.log(timeValue)
    this.timeChanged.emit(timeValue);
  }
}
  1. Run Ionic serve in Mozilla or Chrome
  2. Select device view and choose iPad Pro or any tablet
  3. Change the selected option

Ionic Info

Versions:
Ionic:

Ionic CLI : 7.2.0
Ionic Framework : @ionic/angular 8.5.0
@angular-devkit/build-angular : 18.2.15
@angular-devkit/schematics : 18.2.15
@angular/cli : 18.2.15
@ionic/angular-toolkit : 11.0.1

Capacitor:

Capacitor CLI : 7.1.0
@capacitor/android : 7.0.1
@capacitor/core : 7.1.0
@capacitor/ios : 7.0.1

Utility:

cordova-res : 0.15.4
native-run : 2.0.1

System:

NodeJS : v22.12.0
npm : 10.9.0
OS : Linux 5.15

Additional Information

No response

Activity

  1. MikelMoli commented on Mar 25, 2025

    @MikelMoli
    Author

    Just in case someone need a workaround...

    This can be fixed by changing the font-size of the component ion-picker-column-option. It seems like if the font size is too big, the wheel spins to the top values and if the font size is too small it spins to the values on the bottom. So the only way I found that it doesn't spin and stays in the selected values is to pick a font that is not too big nor too small.

    The problem here is that you will need to set different font-sizes for different media devices, and even like that the widget might not good look when is functioning OK.

    This issue seems to be related with this one: #29713

  2. ShaneK commented on May 7, 2025

    @ShaneK
    Member

    Hello! Could you please replicate this on maybe Stackblitz or something? I'm having a hard time reproducing this issue currently.

  3. ionitron-bot commented on May 7, 2025

    @ionitron-bot

    Thanks for the issue! This issue has been labeled as needs reproduction. This label is added to issues that need a code reproduction.

    Please reproduce this issue in an Ionic starter application and provide a way for us to access it (GitHub repo, StackBlitz, etc). Without a reliable code reproduction, it is unlikely we will be able to resolve the issue, leading to it being closed.

    If you have already provided a code snippet and are seeing this message, it is likely that the code snippet was not enough for our team to reproduce the issue.

    For a guide on how to create a good reproduction, see our Contributing Guide.

  4. loic-parent commented on May 12, 2025

    @loic-parent

    Hello, I'm encountering the same issue/behavior with the ion-picker.
    I didn't have this with the PickerController (that I used before).

    In my case, this happens when the user change the global font-size settings of the Android phone (Settings > Screen > Font and screen zoom).

    Here is the render:

    Image

    To reproduce it, this is simple:

    1. Create Ionic project.
    2. Add ion-picker with multiple items inside.
    3. ionic cap run android --open
    4. Install the app on phone or simulator.
    5. Go to phone settings and change the font-size (bigger).
    6. Open the app and scroll in the picker options to see the bug.

    Hope this can help to identify and fix this.

    Kind regards,
    Loïc

  5. loic-parent commented on May 12, 2025

    @loic-parent

    Hi again,

    One way to "fix" this is to force the textZoom of the webview at 100% and so don't apply changes related to user text settings:
    File: MainActivity.java

    import android.os.Bundle;
    import com.getcapacitor.BridgeActivity;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    
    public class MainActivity extends BridgeActivity {
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        WebView webView = (WebView) this.bridge.getWebView();
        WebSettings webSettings = webView.getSettings();
        webSettings.setTextZoom(100); // ← Change automatic/user scalling.
      }
    }

    This is not very goof for accessibility because the settings will be skipped but this will ensure that the font-size defined in the code/styles will be used in the app/webview.

    So, this one "solve" the issue related to the settings (not for custom styles with bigger font-size).

    Kind regards,
    Loïc

  6. thetaPC commented on May 20, 2025

    @thetaPC
    Contributor

    Thank you for the issue!

    Closing this issue as it's a duplicate of #29713. I recommend subscribing to the original issue for updates.

  7. ionitron-bot commented on Jun 19, 2025

    @ionitron-bot

    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.

  8. locked and limited conversation to collaborators on Jun 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions