Skip to content

Conversation

@BagavathiPerumal
Copy link
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Root cause

The issue occurs because the TAB key triggers an EditingDidEnd event that persists when the picker reopens. When the picker opens, EditingDidBegin presents the UIAlertController, but immediately after, another EditingDidEnd event fires due to the lingering focus state. The original code dismissed the picker in the EditingDidEnd handler, causing the picker to close instantly after opening and breaking keyboard navigation.

Regression PR: #27973

Description of Issue Fix

The fix involves separating how the picker responds to different dismissal triggers. It removes automatic dismissal from the EditingDidEnd handler, which now only updates the IsFocused and IsOpen state. A new MapUnfocus command handler is added for MacCatalyst that stores a reference to the active UIAlertController and dismisses it only when Unfocus() is called programmatically. This distinguishes between TAB-induced events (no dismissal) and explicit unfocus commands (dismissal), fixing the keyboard navigation issue while maintaining compatibility with existing focus behavior.

Tested the behavior in the following platforms.

  • Mac
  • Windows
  • iOS
  • Android

Issues Fixed

Fixes #33463

Output

Before Issue Fix After Issue Fix
PickerDialogIssue-BeforeFix.mov
PickerDialogIssue-AfterFix.mov

…or MacCatalyst that explicitly dismisses the picker only on programmatic unfocus calls, while removing automatic dismissal from EditingDidEnd handler to prevent TAB-induced immediate closure.
@sheiksyedm
Copy link
Contributor

/azp run maui-pr-uitests 

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

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 fixes a macOS-specific issue where the Picker dialog closes immediately when opened using the Tab key. The root cause was that pressing Tab triggers an EditingDidEnd event that persisted when the picker reopens, causing the picker to dismiss immediately after opening. This was a regression from PR #27973.

Changes:

  • Removed automatic dismissal from the EditingDidEnd handler, which now only updates IsFocused and IsOpen state
  • Added MapUnfocus command handler for MacCatalyst that dismisses the UIAlertController only when Unfocus() is called programmatically
  • Added Focus/Unfocus command mappings to the CommandMapper for MACCATALYST platform
  • Added a UI test to verify the picker remains open when accessed via Tab key

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/Core/src/Handlers/Picker/PickerHandler.iOS.cs Adds _currentPickerController field to track active picker, modifies EditingDidEnd to only update state (not dismiss), adds MapFocus and MapUnfocus handlers for MacCatalyst
src/Core/src/Handlers/Picker/PickerHandler.cs Extends CommandMapper to include Focus/Unfocus commands for MACCATALYST in addition to ANDROID
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33463.cs Adds UI test that verifies picker stays open after Tab key navigation
src/Controls/tests/TestCases.HostApp/Issues/Issue33463.cs Adds test page with Picker and Entry controls for testing Tab navigation

Comment on lines +65 to +66
_currentPickerController = UIAlertController.Create("", "", UIAlertControllerStyle.ActionSheet);
var pickerController = _currentPickerController;
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If DisplayAlert is called while _currentPickerController is not null (for example, if the picker is already open and DisplayAlert is called again), the code will create a new UIAlertController and overwrite the _currentPickerController reference without dismissing the previous one. This could lead to multiple picker dialogs being displayed simultaneously or leaked view controllers.

Consider adding a guard at the start of DisplayAlert to check if _currentPickerController is not null, and if so, either dismiss it first or return early to prevent duplicate displays.

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +29
Task.Delay(800).Wait();

var doneButton = App.FindElement("Done");
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After SendTabKey(), the test should verify that the picker opens before checking for the Done button. Currently, it relies on a fixed delay and then uses FindElement which may return null without waiting. If the picker hasn't opened yet, FindElement("Done") will fail.

The test should use WaitForElement instead of Task.Delay + FindElement:

  • Remove: Task.Delay(800).Wait(); var doneButton = App.FindElement("Done");
  • Use: var doneButton = App.WaitForElement("Done", timeout: TimeSpan.FromSeconds(2));

This ensures the test waits for the picker to open rather than assuming 800ms is sufficient.

Copilot generated this review using guidance from repository custom instructions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-picker Picker community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/macos macOS / Mac Catalyst

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[macOS]Picker items are not visible

3 participants