Skip to content

bug: ionChange not fired on iOS 16 devices for ion-picker  #29672

Open
@Simon54

Description

@Simon54

Prerequisites

Ionic Framework Version

v8.x

Current Behavior

By scrolling the picker the value is not changed and the event is not fired on iOS devices with iOS 16 (used iPhone 8 Plus).

Expected Behavior

The event should fire and the value should change.

Steps to Reproduce

  1. create a blank angular ionic project
  2. Insert code as the documentation in the home.page.html,home.poge.ts and home.page.scss files: https://ionicframework.com/docs/api/picker#picker-in-modal
  3. To check the bug add in home.page.ts one line to the onIonChange function:
  onIonChange(event: CustomEvent) {
    console.log("onIonChange fired!", event.detail.value) // ADD THIS LINE
    this.currentValue = event.detail.value;  
  }
  1. Try on an Android device: you see in the console the ionChange event fired when value change
  2. Try on an iOS device: nothing is fired when value change

Code Reproduction URL

https://github.com/losciur/ionic-bug-ion-column-picker

Ionic Info

Ionic:

Ionic CLI : 5.4.16 (/Users/simon/.npm/_npx/864a9e3c2cd0cf50/node_modules/ionic)

Capacitor:

Capacitor CLI : 6.1.0
@capacitor/core : 6.1.0

Utility:

cordova-res : 0.15.4
native-run : 2.0.0

System:

NodeJS : v22.3.0 (/usr/local/Cellar/node/22.3.0/bin/node)
npm : 10.8.1
OS : macOS Unknown

Additional Information

The code is from this closed issue: #29480

The issue was closed without it having been resolved, so I'm reopening it, because it is happening on an iPhone that has iOS 16 and should be supported, since these devices don't receive iOS 17.

I investigated the issue and it comes down to the elementsForPoint not returning the ion-picker-column-option on this devices for some reason. So I made a simple patch which would make it work, but it's probably a bit expensive:

/core/src/components/picker-column/picker-column.tsx 379:

let newActiveElement = elementsAtPoint.find((el) => el.tagName === 'ION-PICKER-COLUMN-OPTION');
if(!newActiveElement) {
    const contains = (rect,x,y)=>rect.x <= x && rect.y <= y && x <= rect.x + rect.width && y <= rect.y + rect.height
    newActiveElement = [...el.children].find(x=>contains(x.getBoundingClientRect(),centerX,centerY))
}
if (activeEl !== undefined) {
    this.setPickerItemActiveState(activeEl, false);
}

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