-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Improved Unfocus support for Picker on Mac Catalyst #33127
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
base: main
Are you sure you want to change the base?
Conversation
Introduces the MapUnfocus mapping for the PickerHandler on Mac Catalyst, enabling proper dismissal of the picker controller and updating focus state. Refactors related code to store the UIAlertController instance and ensures IsFocused and IsOpen are set to false when the picker is dismissed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR enhances MacCatalyst Picker functionality by implementing proper programmatic dismissal via the Unfocus command, addressing issue #30897. The implementation enables external code to close the picker dialog and properly manages focus states.
Key changes:
- Added UIAlertController instance tracking for MacCatalyst to enable programmatic dismissal
- Implemented MapUnfocus command handler to support Unfocus() API on MacCatalyst
- Simplified dismiss logic by removing duplicate event handlers
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/Core/src/Handlers/Picker/PickerHandler.iOS.cs | Added MacCatalyst-specific pickerController field, implemented MapUnfocus method for programmatic dismissal, and streamlined dismiss logic by removing EditingDidEnd event handler |
| src/Core/src/Handlers/Picker/PickerHandler.cs | Registered Unfocus command in CommandMapper for MacCatalyst platform |
| internal static void MapUnfocus(IPickerHandler handler, IPicker picker, object? args) | ||
| { | ||
| if (handler is PickerHandler pickerHandler && pickerHandler.pickerController != null) | ||
| { | ||
| pickerHandler.pickerController.DismissViewControllerAsync(true); |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The async method DismissViewControllerAsync is called without awaiting its completion. This could cause the IsFocused and IsOpen state updates on lines 162 to execute before the dismissal animation completes, potentially leading to race conditions or inconsistent UI state. Consider awaiting the dismissal or using the non-async variant DismissViewController if immediate execution is required.
| internal static void MapUnfocus(IPickerHandler handler, IPicker picker, object? args) | |
| { | |
| if (handler is PickerHandler pickerHandler && pickerHandler.pickerController != null) | |
| { | |
| pickerHandler.pickerController.DismissViewControllerAsync(true); | |
| internal static async Task MapUnfocus(IPickerHandler handler, IPicker picker, object? args) | |
| { | |
| if (handler is PickerHandler pickerHandler && pickerHandler.pickerController != null) | |
| { | |
| await pickerHandler.pickerController.DismissViewControllerAsync(true); |
| UIPickerView? _pickerView; | ||
|
|
||
| #if MACCATALYST | ||
| UIAlertController? pickerController; |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The instance field pickerController should be cleaned up in the DisconnectHandler method to prevent potential memory leaks. When the handler is disconnected, the pickerController reference may still hold onto UIKit resources. Add cleanup logic to dismiss and null out this field in DisconnectHandler, similar to how _pickerView is cleaned up.
| UIPickerView? _pickerView; | ||
|
|
||
| #if MACCATALYST | ||
| UIAlertController? pickerController; |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The field name "pickerController" does not follow the C# naming convention for private/internal fields, which typically use an underscore prefix (e.g., _pickerController). This is inconsistent with other fields in the same class like "_proxy" and "_pickerView".
PR Changes - MacCatalyst Picker Improvements
Fixes #30897
Fixes #30891
Overview
Improved MacCatalyst Picker implementation with proper focus management
Changes Made
1. PickerHandler.iOS.cs - MacCatalyst-specific improvements
Added UIAlertController instance field
UIAlertController? pickerControlleras an instance field to enable proper dismissal viaUnfocuscommandImproved picker dismiss logic
EditingDidEndevent handler that was causing duplicate dismiss callsAdded MapUnfocus command handler
MapUnfocusmethod for MacCatalyst to programmatically dismiss the pickerIsFocusedandIsOpenstates when dismissed2. PickerHandler.cs - Command mapper registration
Registered Unfocus command for MacCatalyst
#elif MACCATALYSTsection to CommandMappernameof(IPicker.Unfocus)command to enable programmatic picker dismissal on MacCatalystTesting
Issue2339
Platforms Affected
Breaking Changes
None - this is purely an implementation improvement with no API changes.