Description
Prerequisites
- I have read the Contributing Guidelines.
- I agree to follow the Code of Conduct.
- I have searched for existing issues that already report this problem, without success.
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
- create a blank angular ionic project
- 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
- 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;
}
- Try on an Android device: you see in the console the ionChange event fired when value change
- 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);
}