Skip to content

Conversation

@kubaflo
Copy link
Contributor

@kubaflo kubaflo commented Dec 12, 2025

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

  • Declared UIAlertController? pickerController as an instance field to enable proper dismissal via Unfocus command
  • Allows external code to programmatically close the picker dialog

Improved picker dismiss logic

  • Moved picker dismiss logic from event handler to the "Done" button action
  • Removed EditingDidEnd event handler that was causing duplicate dismiss calls
  • Simplified focus state management by handling it directly in the Done action

Added MapUnfocus command handler

  • Implemented MapUnfocus method for MacCatalyst to programmatically dismiss the picker
  • Properly updates IsFocused and IsOpen states when dismissed
  • Includes null checks for safety

2. PickerHandler.cs - Command mapper registration

Registered Unfocus command for MacCatalyst

  • Added #elif MACCATALYST section to CommandMapper
  • Registered nameof(IPicker.Unfocus) command to enable programmatic picker dismissal on MacCatalyst
  • Brings MacCatalyst picker behavior in line with Android implementation

Testing

Issue2339

Platforms Affected

  • MacCatalyst (primary)
  • iOS (no behavior changes, shared code)

Breaking Changes

None - this is purely an implementation improvement with no API changes.

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.
Copilot AI review requested due to automatic review settings December 12, 2025 01:01
@kubaflo kubaflo self-assigned this Dec 12, 2025
@dotnet-policy-service dotnet-policy-service bot added the community ✨ Community Contribution label Dec 12, 2025
@kubaflo kubaflo added platform/macos macOS / Mac Catalyst area-controls-picker Picker t/a11y Relates to accessibility and removed community ✨ Community Contribution labels Dec 12, 2025
Copy link
Contributor

Copilot AI left a 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

Comment on lines +161 to +165
internal static void MapUnfocus(IPickerHandler handler, IPicker picker, object? args)
{
if (handler is PickerHandler pickerHandler && pickerHandler.pickerController != null)
{
pickerHandler.pickerController.DismissViewControllerAsync(true);
Copy link

Copilot AI Dec 12, 2025

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.

Suggested change
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);

Copilot uses AI. Check for mistakes.
UIPickerView? _pickerView;

#if MACCATALYST
UIAlertController? pickerController;
Copy link

Copilot AI Dec 12, 2025

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.

Copilot uses AI. Check for mistakes.
UIPickerView? _pickerView;

#if MACCATALYST
UIAlertController? pickerController;
Copy link

Copilot AI Dec 12, 2025

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".

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-picker Picker platform/macos macOS / Mac Catalyst t/a11y Relates to accessibility

Projects

None yet

1 participant