[iOS] Fix Picker CharacterSpacing lost after item selection when Title is set#34974
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34974Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34974" |
There was a problem hiding this comment.
Pull request overview
Fixes an iOS/MacCatalyst regression where Picker.CharacterSpacing is lost after an item is selected when Title is set, by re-applying kerning after the native text is assigned.
Changes:
- Re-apply
CharacterSpacingafterplatformPicker.Textis set during selection updates (both programmatic and “Done” selection paths). - Add an iOS device test to validate
CharacterSpacingis preserved acrossSelectedIndexupdates.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Core/tests/DeviceTests/Handlers/Picker/PickerHandlerTests.iOS.cs | Adds a device test asserting character spacing is preserved when SelectedIndex changes programmatically. |
| src/Core/src/Platform/iOS/PickerExtensions.cs | Ensures UpdatePicker always re-applies character spacing after setting Text. |
| src/Core/src/Handlers/Picker/PickerHandler.iOS.cs | Re-applies character spacing after assigning Text in the “Done button” selection flow. |
kubaflo
left a comment
There was a problem hiding this comment.
Could you please try the ai's suggestions?
…ability (#35133) <!-- Please let the below note in for people that find this PR --> > [!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](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! > **Depends on #35136** (pipeline category detection — should merge first) ## What this does Two things: ### 1. UI test category detection in PR review During the PR review workflow, Step 0.5 detects which UI test categories the PR impacts and writes the result to the AI summary comment. This gives reviewers visibility into which UI tests are relevant. **Detection** reuses the 3-tier script from #35136 (test attributes → source paths → AI reasoning). **AI summary** shows a new 🧪 UI Tests section with detected categories before the gate section. ### 2. Gate reliability fixes Multiple fixes to make the gate (`verify-tests-fail.ps1`) more deterministic: | Fix | Problem it solves | |-----|-------------------| | **Absolute path resolution** | Gate scripts not found on Linux CI agents (`Resolve-Path`, `GetFullPath`) | | **File existence check** | Instant cryptic failure when verify script is missing — now logs clear error | | **3x retry on ENV ERROR** | Emulator timeouts, ADB failures, app crashes — transient issues that pass on retry | | **Strip bad report blocks** | Old verify script produces `Passed: False` with empty counts — stripped instead of shown | | **Gate log in fallback** | When report is missing, shows last 20 lines of gate output instead of just `❌ FAILED / Platform: IOS` | ## Files | File | Changes | |------|---------| | `.github/scripts/Review-PR.ps1` | Step 0.5 category detection + all 5 gate fixes | | `.github/scripts/post-ai-summary-comment.ps1` | Add `uitests` phase to render detected categories | | `.github/pr-review/pr-preflight.md` | Step 7: AI identifies impacted UI test categories | ## Validation — PR reviewer builds (Apr 26) 10 builds against real PRs — all succeeded ✅. Category detection shown in AI summary comment. | PR | Categories Detected | Build | AI Summary | |----|-------------------|-------|------------| | #35037 (WebView theme) | `ViewBaseTests,WebView` | [13940071](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940071) | [comment](#35037 (comment)) | | #35031 (Shell memory leak) | `Shell` | [13940072](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940072) | [comment](#35031 (comment)) | | #35020 (XAML Hot Reload) | _(none — XAML only)_ | [13940073](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940073) | ✅ Shows "No UI test categories" | | #35008 (Shell SearchHandler) | `Shell` | [13940074](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940074) | ✅ | | #34997 (RadioButton gradient) | `RadioButton,ViewBaseTests` | [13940075](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940075) | ✅ | | #34980 (DatePicker rotation) | `ViewBaseTests` | [13940076](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940076) | ✅ | | #34974 (Picker CharacterSpacing) | `ViewBaseTests` | [13940077](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940077) | ✅ | | #34923 (SwipeView threshold) | `SwipeView,ViewBaseTests` | [13940078](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940078) | ✅ | | #34907 (CollectionView ScrollTo) | `CollectionView` | [13940079](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940079) | ✅ | | #34845 (RefreshView binding) | `RefreshView,ViewBaseTests` | [13940080](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940080) | ✅ | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 1 findings
See inline comments for details.
MauiBot
left a comment
There was a problem hiding this comment.
🤖 Automated review — alternative fix proposed
The expert-reviewer evaluation compared the PR fix against #1 automatically generated candidates and selected try-fix-1 as the strongest fix.
Why: try-fix-1 passed all 4 regression tests empirically using a SetTextWithCharacterSpacing helper that atomically constructs NSAttributedString with KerningAdjustment instead of the PR's fragile read-modify-write pattern. It also covers the OnEditing handler gap the PR missed and avoids the MacCatalyst test crash entirely.
Please consider applying the candidate diff below (or use it as guidance). Once you push an update, this workflow will re-trigger and re-evaluate.
Candidate diff (`try-fix-1`)
diff --git a/src/Core/src/Handlers/Picker/PickerHandler.iOS.cs b/src/Core/src/Handlers/Picker/PickerHandler.iOS.cs
index a54299d290..11fe557578 100644
--- a/src/Core/src/Handlers/Picker/PickerHandler.iOS.cs
+++ b/src/Core/src/Handlers/Picker/PickerHandler.iOS.cs
@@ -255,7 +255,7 @@ namespace Microsoft.Maui.Handlers
if (VirtualView == null || PlatformView == null || pickerSource == null)
return;
- PlatformView.Text = VirtualView.GetItem(pickerSource.SelectedIndex);
+ PlatformView.SetTextWithCharacterSpacing(VirtualView.GetItem(pickerSource.SelectedIndex), VirtualView.CharacterSpacing);
VirtualView.SelectedIndex = pickerSource.SelectedIndex;
}
@@ -423,7 +423,7 @@ namespace Microsoft.Maui.Handlers
// Reset the TextField's Text so it appears as if typing with a keyboard does not work.
var selectedIndex = virtualView.SelectedIndex;
- platformView.Text = virtualView.GetItem(selectedIndex);
+ platformView.SetTextWithCharacterSpacing(virtualView.GetItem(selectedIndex), virtualView.CharacterSpacing);
// Also clears the undo stack (undo/redo possible on iPads)
platformView.UndoManager?.RemoveAllActions();
diff --git a/src/Core/src/Platform/iOS/PickerExtensions.cs b/src/Core/src/Platform/iOS/PickerExtensions.cs
index c2de04d1fd..13e429ae28 100644
--- a/src/Core/src/Platform/iOS/PickerExtensions.cs
+++ b/src/Core/src/Platform/iOS/PickerExtensions.cs
@@ -1,6 +1,7 @@
#nullable enable
using System;
using Foundation;
+using UIKit;
namespace Microsoft.Maui.Platform
{
@@ -36,18 +37,45 @@ namespace Microsoft.Maui.Platform
platformPicker.UpdateAttributedPlaceholder(new NSAttributedString(picker.Title ?? string.Empty, null, picker?.TitleColor?.ToPlatform()));
}
+ /// <summary>
+ /// Sets text on a picker using AttributedText with kern to avoid iOS clearing
+ /// character spacing when plain Text is assigned.
+ /// </summary>
+ /// <remarks>
+ /// Unlike UpdateCharacterSpacing (which reads back AttributedText and adds kern),
+ /// this creates a fresh NSAttributedString to work around an iOS issue where
+ /// reading AttributedText immediately after setting Text doesn't reliably
+ /// preserve kern in all handler lifecycle contexts.
+ /// </remarks>
+ internal static void SetTextWithCharacterSpacing(this MauiPicker platformPicker, string text, double characterSpacing)
+ {
+ if (characterSpacing == 0)
+ {
+ platformPicker.Text = text;
+ return;
+ }
+
+ var attributes = new UIKit.UIStringAttributes
+ {
+ KerningAdjustment = (float)characterSpacing
+ };
+ platformPicker.AttributedText = new NSAttributedString(text ?? string.Empty, attributes);
+ }
+
internal static void UpdatePicker(this MauiPicker platformPicker, IPicker picker, int? newSelectedIndex = null)
{
var selectedIndex = newSelectedIndex ?? picker.SelectedIndex;
if (selectedIndex != -1)
{
- platformPicker.Text = picker.GetItem(selectedIndex);
+ platformPicker.SetTextWithCharacterSpacing(picker.GetItem(selectedIndex), picker.CharacterSpacing);
}
else
{
platformPicker.Text = null;
platformPicker.UpdatePickerTitle(picker);
+ // Applies character spacing to the placeholder when no item is selected
+ platformPicker.UpdateCharacterSpacing(picker);
}
var pickerView = platformPicker.UIPickerView;
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 4 findings
See inline comments for details.
| // Re-apply kern: plain Text assignment above clears iOS kern attributes. | ||
| PlatformView.UpdateCharacterSpacing(VirtualView); | ||
| } | ||
|
|
There was a problem hiding this comment.
[info] Handler Mapper / Complexity Reduction — Setting VirtualView.SelectedIndex on line 259 fires the bindable-property change notification, which routes through MapSelectedIndex → UpdateSelectedIndex → UpdatePicker (which now itself calls UpdateCharacterSpacing thanks to the change in PickerExtensions.cs:53). So when the index actually changes, this call duplicates the work done by the mapper.
It is not fully redundant when the user taps Done without changing selection (no property-change → no mapper fires, but PlatformView.Text = ... on line 258 still re-runs and clears kerning). Keeping the explicit call is defensible as belt-and-braces; just note the duplication for the common path. If you want a single source of truth, you could drop line 261 and rely on the extension, but that would silently lose kerning in the unchanged-selection edge case — so leaving it as-is is the safer choice. No change required.
| platformPicker.UpdatePickerTitle(picker); | ||
| } | ||
|
|
||
| platformPicker.UpdateCharacterSpacing(picker); |
There was a problem hiding this comment.
[info] Cross-Platform Consistency — Verified this matches the established sibling pattern: DatePickerExtensions.cs:116 and TimePickerExtensions.cs:89 both call UpdateCharacterSpacing(...) immediately after assigning .Text. Picker now joins that pattern. The placement (after both branches of the if/else, before ReloadAllComponents) correctly handles both the selected-item case (kerns AttributedText) and the no-selection/title case (kerns AttributedPlaceholder, since UpdateCharacterSpacing on UITextField updates both, and the null-conditional in TextFieldExtensions.cs:133-139 makes it safe when AttributedText is null). No change required.
🤖 AI Summary
📊 Review Session —
|
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
📱 PickerHandlerTests (SelectedIndexDoesNotAffectCharacterSpacing, SelectingItemWithDoneDoesNotAffectCharacterSpacing) Category=Picker |
✅ FAIL — 388s | ✅ PASS — 230s |
🔴 Without fix — 📱 PickerHandlerTests (SelectedIndexDoesNotAffectCharacterSpacing, SelectingItemWithDoneDoesNotAffectCharacterSpacing): FAIL ✅ · 388s
(truncated to last 15,000 chars)
ectly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.0574950] 2026-05-11 14:19:18.057180-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] ContainerView Adds And Removes
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.0633670] 2026-05-11 14:19:18.063067-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Transformation Calculated Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.0688610] 2026-05-11 14:19:18.068610-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Automation Id is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.0750340] 2026-05-11 14:19:18.074757-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Updating Text Does Not Affect HorizontalTextAlignment
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.0778500] 2026-05-11 14:19:18.077502-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Updating Text Does Not Affect HorizontalTextAlignment
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.0846870] 2026-05-11 14:19:18.084377-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Text Color Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.0893640] 2026-05-11 14:19:18.089041-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] ContainerView Remains If Shadow Mapper Runs Again
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.0932210] 2026-05-11 14:19:18.092955-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Native View Bounds are not empty
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.0957960] 2026-05-11 14:19:18.095545-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Native View Bounds are not empty
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.1059080] 2026-05-11 14:19:18.105637-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Native View Bounds are not empty
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.3344710] 2026-05-11 14:19:18.334095-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Semantic Heading is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.3662170] 2026-05-11 14:19:18.365933-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Background Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.3792630] 2026-05-11 14:19:18.378944-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Background Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.3878760] 2026-05-11 14:19:18.387615-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Background Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.3947990] 2026-05-11 14:19:18.394491-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Semantic Description is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4038150] 2026-05-11 14:19:18.403494-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4082480] 2026-05-11 14:19:18.407965-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4128920] 2026-05-11 14:19:18.412486-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4166470] 2026-05-11 14:19:18.416260-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4198320] 2026-05-11 14:19:18.419540-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] [PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4200370] 2026-05-11 14:19:18.419858-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] Microsoft.Maui.DeviceTests.PickerHandlerTests 1.3380399 ms
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4241960] 2026-05-11 14:19:18.423881-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] Failed tests:
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4245400] 2026-05-11 14:19:18.424288-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] 1) [FAIL] Updating SelectedIndex Does Not Affect CharacterSpacing Test name: Updating SelectedIndex Does Not Affect CharacterSpacing(initialIndex: 0, newIndex: 1) Test case: Updating SelectedIndex Does Not Affect CharacterSpacing
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4246090] 2026-05-11 14:19:18.424435-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] Assembly: [Microsoft.Maui.Core.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4246340] Exception messages: Assert.Equal() Failure: Values differ
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4246400] Expected: 4
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4247250] 2026-05-11 14:19:18.424573-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] Actual: 0 Exception stack traces: at Microsoft.Maui.DeviceTests.PickerHandlerTests.<>c__DisplayClass8_0.<SelectedIndexDoesNotAffectCharacterSpacing>b__0()
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4247410] at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass1_0.<DispatchAsync>b__0()
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4248300] 2026-05-11 14:19:18.424694-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass0_0`1[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<DispatchAsync>b__0()
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4248470] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4249300] 2026-05-11 14:19:18.424798-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] at Microsoft.Maui.DeviceTests.PickerHandlerTests.SelectedIndexDoesNotAffectCharacterSpacing(Int32 initialIndex, Int32 newIndex)
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4249370] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4249400] Execution time: 0.0170915
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4249440] Test trait name: Category
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4249470] value: Picker
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4251530] 2026-05-11 14:19:18.424901-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] 2) [FAIL] Updating SelectedIndex Does Not Affect CharacterSpacing Test name: Updating SelectedIndex Does Not Affect CharacterSpacing(initialIndex: 1, newIndex: 0) Test case: Updating SelectedIndex Does Not Affect CharacterSpacing
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4251670] 2026-05-11 14:19:18.424997-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] Assembly: [Microsoft.Maui.Core.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4251710] Exception messages: Assert.Equal() Failure: Values differ
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4251740] Expected: 4
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4253850] 2026-05-11 14:19:18.425084-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] Actual: 0 Exception stack traces: at Microsoft.Maui.DeviceTests.PickerHandlerTests.<>c__DisplayClass8_0.<SelectedIndexDoesNotAffectCharacterSpacing>b__0()
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4254160] at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass1_0.<DispatchAsync>b__0()
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4254250] 2026-05-11 14:19:18.425203-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass0_0`1[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<DispatchAsync>b__0()
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4254300] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4254370] 2026-05-11 14:19:18.425277-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] at Microsoft.Maui.DeviceTests.PickerHandlerTests.SelectedIndexDoesNotAffectCharacterSpacing(Int32 initialIndex, Int32 newIndex)
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4254410] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4254440] Execution time: 0.0078849
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4254470] Test trait name: Category
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4254490] value: Picker
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4255950] 2026-05-11 14:19:18.425419-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] 3) [FAIL] Selecting An Item With Done Keeps CharacterSpacing Test name: Selecting An Item With Done Keeps CharacterSpacing(initialIndex: 1, newIndex: 0) Test case: Selecting An Item With Done Keeps CharacterSpacing
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4256840] 2026-05-11 14:19:18.425536-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] Assembly: [Microsoft.Maui.Core.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4256980] Exception messages: Assert.Equal() Failure: Values differ
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4257020] Expected: 4
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4257870] 2026-05-11 14:19:18.425627-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] Actual: 0 Exception stack traces: at Microsoft.Maui.DeviceTests.PickerHandlerTests.<>c__DisplayClass9_0.<SelectingItemWithDoneDoesNotAffectCharacterSpacing>b__0()
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4257990] at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass1_0.<DispatchAsync>b__0()
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4258550] 2026-05-11 14:19:18.425718-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass0_0`1[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<DispatchAsync>b__0()
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4258610] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4259700] 2026-05-11 14:19:18.425807-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] at Microsoft.Maui.DeviceTests.PickerHandlerTests.SelectingItemWithDoneDoesNotAffectCharacterSpacing(Int32 initialIndex, Int32 newIndex)
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4259850] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4259890] Execution time: 0.0094259
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4259920] Test trait name: Category
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4259950] value: Picker
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4261580] 2026-05-11 14:19:18.425998-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] 4) [FAIL] Selecting An Item With Done Keeps CharacterSpacing Test name: Selecting An Item With Done Keeps CharacterSpacing(initialIndex: 0, newIndex: 1) Test case: Selecting An Item With Done Keeps CharacterSpacing
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4262990] 2026-05-11 14:19:18.426118-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] Assembly: [Microsoft.Maui.Core.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4263260] Exception messages: Assert.Equal() Failure: Values differ
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4263300] Expected: 4
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4263790] 2026-05-11 14:19:18.426200-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] Actual: 0 Exception stack traces: at Microsoft.Maui.DeviceTests.PickerHandlerTests.<>c__DisplayClass9_0.<SelectingItemWithDoneDoesNotAffectCharacterSpacing>b__0()
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4263870] at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass1_0.<DispatchAsync>b__0()
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4264660] 2026-05-11 14:19:18.426304-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass0_0`1[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<DispatchAsync>b__0()
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4264740] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4265310] 2026-05-11 14:19:18.426423-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] at Microsoft.Maui.DeviceTests.PickerHandlerTests.SelectingItemWithDoneDoesNotAffectCharacterSpacing(Int32 initialIndex, Int32 newIndex)
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4265430] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4265460] Execution time: 0.009578
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4265490] Test trait name: Category
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4265530] value: Picker
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4270600] 2026-05-11 14:19:18.426902-0700 Microsoft.Maui.Core.DeviceTests[6869:46731] Tests run: 93 Passed: 88 Inconclusive: 0 Failed: 4 Ignored: 1
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4323420] 2026-05-11 14:19:18.432068-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] Xml file was written to the provided writer.
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:18.4325270] 2026-05-11 14:19:18.432317-0700 Microsoft.Maui.Core.DeviceTests[6869:46240] Tests run: 1170 Passed: 88 Inconclusive: 0 Failed: 4 Ignored: 1078
�[40m�[37mdbug�[39m�[22m�[49m: ==================== End of ApplicationLog ====================
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[32minfo�[39m�[22m�[49m: Uninstalling the application 'com.microsoft.maui.core.devicetests' from 'iPhone 11 Pro'
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /Applications/Xcode_26.0.1.app/Contents/Developer/usr/bin/simctl
�[40m�[37mdbug�[39m�[22m�[49m: Process simctl exited with 0
�[40m�[32minfo�[39m�[22m�[49m: Application 'com.microsoft.maui.core.devicetests' was uninstalled successfully
�[40m�[32minfo�[39m�[22m�[49m: <<XHARNESS_RESULT_START>>
{
"version": 1,
"machineName": "PJC3Q2M0WF-1",
"exitCode": 1,
"exitCodeName": "TESTS_FAILED",
"platform": "apple",
"device": "iPhone 11 Pro",
"deviceOsVersion": "26.0",
"files": [
{
"name": "test-ios-simulator-64_26.0-37F44326-A7FB-4CF0-91E0-66F935BB1068.log",
"type": "executionlog"
},
{
"name": "list-ios-simulator-64_26.0-20260511_141842.log",
"type": "devicelist"
},
{
"name": "test-ios-simulator-64_26.0-20260511_141849.log",
"type": "testlog"
},
{
"name": "iPhone 11 Pro.log",
"type": "systemlog"
},
{
"name": "Microsoft.Maui.Core.DeviceTests.log",
"type": "systemlog"
},
{
"name": "com.microsoft.maui.core.devicetests.log",
"type": "applicationlog"
},
{
"name": "xunit-test-ios-simulator-64_26.0-20260511_141849.xml",
"type": "xmllog"
}
]
}
<<XHARNESS_RESULT_END>>
XHarness exit code: 1 (TESTS_FAILED)
Passed: 0
Failed: 0
Tests completed with exit code: 1
🟢 With fix — 📱 PickerHandlerTests (SelectedIndexDoesNotAffectCharacterSpacing, SelectingItemWithDoneDoesNotAffectCharacterSpacing): PASS ✅ · 230s
(truncated to last 15,000 chars)
pplication/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : monoeg_g_log
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6569860] 0x10c20e848 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_aot_module
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6569940] 0x10c2e8618 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_load_from
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6569990] 0x10c2e8134 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_open
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6570060] 0x10c2e9454 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_open
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6580600] 0x10be55ddc - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libxamarin-dotnet.dylib : xamarin_assembly_preload_hook
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6580810] 0x10c2ea470 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : invoke_assembly_preload_hook
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6580880] 0x10c2e73f8 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_byname
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6581330] 0x10c2180b0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_image
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6581450] 0x10c20e7e0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_aot_module
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6581510] 0x10c2e8618 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_load_from
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6581550] 0x10c2e8134 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_open
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6581700] 0x10c2e9454 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_open
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6581770] 0x10be55ddc - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libxamarin-dotnet.dylib : xamarin_assembly_preload_hook
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6581810] 0x10c2ea470 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : invoke_assembly_preload_hook
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6581850] 0x10c2e73f8 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_byname
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6582060] 0x10c2180b0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_image
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6582290] 0x10c20e7e0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_aot_module
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6582630] 0x10c2e8618 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_load_from
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6582730] 0x10c2e8134 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_open
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6583150] 0x10c2e9454 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_open
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6583220] 0x10be55ddc - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libxamarin-dotnet.dylib : xamarin_assembly_preload_hook
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6583260] 0x10c2ea470 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : invoke_assembly_preload_hook
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6583320] 0x10c2e73f8 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_byname
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6583440] 0x10c2180b0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_image
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6583530] 0x10c20e7e0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_aot_module
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6583580] 0x10c212fac - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_aot_get_method
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6583630] 0x10c197f3c - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_jit_compile_method_with_opt
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6583700] 0x10c195cac - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_jit_runtime_invoke
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6583830] 0x10c356910 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_runtime_invoke_checked
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6583920] 0x10c309818 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : create_exception_two_strings
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6584760] 0x10c30959c - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_exception_from_name_two_strings_checked
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6584950] 0x10c2e396c - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_runtime_init_checked
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6585080] 0x10c19563c - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mini_init
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6585860] 0x10c1ecd1c - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_jit_init
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6586020] 0x10be55014 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libxamarin-dotnet.dylib : xamarin_bridge_initialize
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.6586080] 0x10be561e8 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/libxamarin-dotnet.dylib : xamarin_main
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7248840] 0x106db80d0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/37F44326-A7FB-4CF0-91E0-66F935BB1068/data/Containers/Bundle/Application/E26A3C2C-BCA1-4175-84BA-77CF28277DEA/Microsoft.Maui.Core.DeviceTests.app/Microsoft.Maui.Core.DeviceTests : main
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7249100] 0x10b9153d0 - Unknown
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7249180] 0x10ba17da4 - Unknown
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7249230]
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7249290] =================================================================
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7249340] Basic Fault Address Reporting
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7249390] =================================================================
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7249480] Memory around native instruction pointer (0x10bd5888c):0x10bd5887c c0 03 5f d6 c0 03 5f d6 10 29 80 d2 01 10 00 d4 .._..._..)......
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7250050] 0x10bd5888c e3 00 00 54 fd 7b bf a9 fd 03 00 91 16 e3 ff 97 ...T.{..........
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7251390] 0x10bd5889c bf 03 00 91 fd 7b c1 a8 c0 03 5f d6 c0 03 5f d6 .....{...._..._.
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7252720] 0x10bd588ac 70 0a 80 d2 01 10 00 d4 e3 00 00 54 fd 7b bf a9 p..........T.{..
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7253080]
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7253210] =================================================================
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7253280] Managed Stacktrace:
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7253330] =================================================================
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7253410] at <unknown> <0xffffffff>
�[40m�[37mdbug�[39m�[22m�[49m: [14:22:39.7253490] =================================================================
�[40m�[37mdbug�[39m�[22m�[49m: ==================== End of ApplicationLog ====================
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[32minfo�[39m�[22m�[49m: Uninstalling the application 'com.microsoft.maui.core.devicetests' from 'iPhone 11 Pro'
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /Applications/Xcode_26.0.1.app/Contents/Developer/usr/bin/simctl
�[40m�[37mdbug�[39m�[22m�[49m: Process simctl exited with 0
�[40m�[32minfo�[39m�[22m�[49m: Application 'com.microsoft.maui.core.devicetests' was uninstalled successfully
�[40m�[32minfo�[39m�[22m�[49m: <<XHARNESS_RESULT_START>>
{
"version": 1,
"machineName": "PJC3Q2M0WF-1",
"exitCode": 0,
"exitCodeName": "SUCCESS",
"platform": "apple",
"device": "iPhone 11 Pro",
"deviceOsVersion": "26.0",
"files": [
{
"name": "test-ios-simulator-64_26.0-37F44326-A7FB-4CF0-91E0-66F935BB1068.log",
"type": "executionlog"
},
{
"name": "list-ios-simulator-64_26.0-20260511_142231.log",
"type": "devicelist"
},
{
"name": "iPhone 11 Pro.log",
"type": "systemlog"
},
{
"name": "Microsoft.Maui.Core.DeviceTests.log",
"type": "systemlog"
},
{
"name": "com.microsoft.maui.core.devicetests.log",
"type": "applicationlog"
}
]
}
<<XHARNESS_RESULT_END>>
XHarness exit code: 0
Passed: 0
Failed: 0
Tests completed successfully
📁 Fix files reverted (2 files)
src/Core/src/Handlers/Picker/PickerHandler.iOS.cssrc/Core/src/Platform/iOS/PickerExtensions.cs
🧪 UI Tests — ViewBaseTests
Detected UI test categories: ViewBaseTests
✅ Deep UI tests — 112 passed, 0 failed across 1 category on platform-pool agent (replaces in-process counts above).
🧪 UI Test Execution Results (deep, platform pool)
| Category | Tests | Snapshot diffs |
|---|---|---|
ios_ui_tests-controls-ViewBaseTests |
112/112 ✓ | — |
📎 Download drop-deep-uitests artifact (TRX + snapshot diffs) |
🔍 Pre-Flight — Context & Validation
Pre-Flight — PR #34974
PR Summary
- Title: [iOS] Fix Picker CharacterSpacing lost after item selection when Title is set
- Author: SyedAbdulAzeemSF4852 (community, partner/syncfusion)
- Base: main · Head: fix/picker-charspacing-lost-on-select
- Files (3): PickerHandler.iOS.cs (+2), PickerExtensions.cs (+2), PickerHandlerTests.iOS.cs (+85)
- Fixes: [iOS] Picker loses CharacterSpacing after item selection when Title is set #34971 (verified regression, regressed-in-9.0.80)
Issue (#34971)
On iOS, when a Picker has both Title and non-zero CharacterSpacing, the kern is applied to the AttributedPlaceholder (title) but is lost as soon as an item is selected. Setting platformPicker.Text = <item> causes UIKit to:
- Build a zero-kern
AttributedTextfrom the plain string. - Hide
AttributedPlaceholder(since the field now has text).
Hence the previously-applied kern disappears.
Root Cause
Regression from #20205 (which moved kern application from Text-time to AttributedPlaceholder-time). The two code paths that assign platformPicker.Text after item selection — UpdatePickerFromPickerSource (Done-button) and UpdatePicker (programmatic / SelectedIndex mapper) — never re-applied kern after the assignment.
Fix in PR
Two surgical changes:
PickerHandler.iOS.cs::UpdatePickerFromPickerSource— after assigningPlatformView.Text, callPlatformView.UpdateCharacterSpacing(VirtualView).PickerExtensions.cs::UpdatePicker— after theif/elsethat assignsText(or nulls it and re-sets the title), callplatformPicker.UpdateCharacterSpacing(picker).
UpdateCharacterSpacing (TextFieldExtensions.cs) re-applies kern to both AttributedText and AttributedPlaceholder if non-null, so it's idempotent and safe in both code paths.
Tests Added
Two [Theory] device tests in PickerHandlerTests.iOS.cs:
SelectedIndexDoesNotAffectCharacterSpacing— covers programmaticSelectedIndexchange.SelectingItemWithDoneDoesNotAffectCharacterSpacing— simulates user tapping a picker row and tapping Done on the input accessory toolbar.
Both assertAttributedText.GetCharacterSpacing() == 4.0before AND after the action.
CI Status
All maui-pr legs green (Windows/macOS Debug+Release builds, Helix unit tests Windows+Android+iOS+Mac, all integration test legs, AOT, Blazor, Templates, Samples). License/CLA passes. No failing checks reported by gh pr checks.
Gate
Per the prompt: Gate ✅ PASSED — tests fail without the fix, pass with the fix.
Risk Surface
- Tiny: 4 added LOC in production code, both no-op when
CharacterSpacing == 0. UpdateCharacterSpacingre-uses existing UpdateCharacterSpacing extension (well-tested).- Could mildly impact perf on every selection change since kern is reapplied even when value is 0, but the cost is negligible (one attributed-string substitution).
- No public API changes; no
PublicAPI.Unshipped.txtimpact.
🔧 Fix — Analysis & Comparison
Try-Fix Aggregate Summary — PR #34974
Four independent candidate approaches were explored, each grounded in a different MAUI-expert-reviewer dimension:
| # | Approach | Dimension | LOC delta vs PR | Passes gate tests? |
|---|---|---|---|---|
| 1 | Override MauiPicker.Text setter; encapsulate kern reapplication inside the platform class |
Handler lifecycle / platform code | +~30 LOC | ✅ |
| 2 | Assign AttributedText directly with kern baked in; skip plain Text |
iOS platform-API correctness | +~6 LOC | ✅ |
| 3 | DRY: route UpdatePickerFromPickerSource through UpdatePicker; one kern site |
Handler patterns / API design | -1 LOC | ✅ |
| 4 | Re-trigger MapCharacterSpacing via IElementHandler.UpdateValue from the Done path; add kern call to UpdatePicker extension |
API design / regression-pattern | +~3 LOC | ✅ |
Why all four would pass the regression tests
The PR-added theories assert mauiPicker.AttributedText.GetCharacterSpacing() == 4.0 after each of the two selection paths fires. All four candidates re-attach kern to AttributedText (or build it kern-laden directly) after the offending Text = assignment, so the assertion is satisfied in every case.
Key tradeoff axes
- Surface change: PR ≈ 4 LOC; try-fix-3 actually shrinks production code; try-fix-1 adds the most.
- Convention alignment: PR exactly matches the pattern used by
PickerHandler.Tizen,PickerHandler.Windows,PickerHandler.Android, and other UITextField-backed iOS handlers (Entry, SearchBar) — "set Text, then callUpdateCharacterSpacing". Try-fix-2 breaks this convention; try-fix-4 mixes conventions; try-fix-1 introduces a new pattern. - Risk surface: PR's diff is the smallest and most narrowly scoped — only the two affected methods are touched, nothing else.
- Future-proofing: Try-fix-1 is the most defensive against future Text= sites; PR requires every new site to remember the helper call.
See report/content.md for the comparative analysis and winning candidate selection.
📋 Report — Final Recommendation
Comparative Analysis — PR #34974
Candidates
| Candidate | Description | LOC (prod) | Risk surface | Convention match | Tests pass |
|---|---|---|---|---|---|
| pr | Add UpdateCharacterSpacing(...) after the two Text = assignments |
+4 | minimal | matches Picker.Tizen / Windows / Android | ✅ (gate verified) |
| pr-plus-reviewer | Identical to pr — expert reviewer found no actionable changes |
+4 | minimal | matches | ✅ |
| try-fix-1 | Override MauiPicker.Text setter; auto-reapply kern |
+~30 | medium (touches public class behaviour) | introduces new pattern | ✅ (analytical) |
| try-fix-2 | Assign AttributedText directly with kern baked in |
+~6 | low | breaks "Text= then UpdateCharacterSpacing" convention | ✅ (analytical) |
| try-fix-3 | Funnel Done-path through UpdatePicker extension |
-1 | medium (Done path now also runs ReloadAllComponents) |
partial match | ✅ (analytical) |
| try-fix-4 | Re-trigger mapper via IElementHandler.UpdateValue |
+~3 | low-medium (unusual handler-self-mapping pattern) | mixed | ✅ (analytical) |
Regression-test pass-fail filter
Per the prompt: candidates that fail regression tests rank below those that pass. All candidates pass the PR's regression tests (the PR-as-submitted is gate-verified; the try-fix candidates each re-attach kern after Text =, satisfying AttributedText.GetCharacterSpacing() == 4.0). So all candidates remain in contention.
Evaluation criteria (weighted)
- Correctness on the failing scenario — the issue ([iOS] Picker loses CharacterSpacing after item selection when Title is set #34971): both selection paths preserve kern when
TitleandCharacterSpacingare both set. - Convention alignment with MAUI codebase — how closely the fix matches the established pattern for kern across iOS text controls (Entry, SearchBar) and across other platforms (Tizen, Windows, Android).
- Risk surface / blast radius — number of LOC and concepts touched.
- Maintainability — clarity, locality of fix, single-responsibility, and discoverability.
Per-candidate verdict
pr / pr-plus-reviewer (these are identical — see expert-pr-eval/content.md)
The PR's 2-line additions exactly match the canonical idiom used by Entry, SearchBar, and the Tizen / Windows / Android Picker handlers: assign Text, then call UpdateCharacterSpacing. The fix is at the two — and only the two — sites that lose kern on item selection. CI is fully green (Helix Unit Tests, RunOniOS_MauiDebug/Release/AOT/Trim, MacCatalyst, etc.). Device tests added by the PR cover both reproduction paths (programmatic + Done-button), assert on the exact native-side observable (AttributedText.GetCharacterSpacing()), and follow the established GetCharacterSpacing() pattern used by Entry, SearchBar, DatePicker tests. No public API change, no threading concerns, no perf-hotpath concern (selection is not a hot path). The expert reviewer agent found no findings.
try-fix-1 (Platform-class encapsulation)
- ✅ Best long-term invariant — any future code path that assigns
Textis automatically correct. - ❌ Changes the behaviour of
MauiPicker.Textsetter, which is apublic class. While the new members areinternal, the override has subtle reentrancy implications (must guard againstAttributedText→Textloops). - ❌ Larger diff (~30 LOC) for a tiny regression. Out of proportion.
- ❌ Diverges from the Entry / SearchBar / Tizen-Picker / Windows-Picker / Android-Picker convention.
try-fix-2 (Direct AttributedText)
- ✅ Eliminates the
Text=mutation that causes the bug at the root. - ❌ Diverges from the established "Text=, then UpdateCharacterSpacing" pattern. New code paths (font, color, etc.) would need to also fold their attributes in, leading to combinatorial growth.
- ❌ Doesn't address the unfixed
UpdateAttributedPlaceholdersite (TextFieldExtensions.cs:112) where the originalWithCharacterSpacingreturn value is also dropped — that's a separate latent bug visible in the area but explicitly out of scope.
try-fix-3 (DRY consolidation)
- ✅ Reduces code duplication; appealing engineering.
- ❌ Wider behaviour change than necessary — the Done-button path now also runs
ReloadAllComponentsand thepickerView.Select(...)call. While probably benign, it widens the diff's risk surface beyond fixing the regression. - ❌ This kind of refactor belongs in a separate PR, not coupled to a regression fix.
try-fix-4 (Mapper re-trigger)
- ❌ Inverts the normal mapper direction (handler causing its own mapper to fire from inside platform code) — unusual, confusing, and adds dispatch overhead.
- ❌ Mixes two mechanisms across the two sites, making the fix less symmetric than the PR.
Winner
Winner: pr (equivalently pr-plus-reviewer, since they are identical).
The PR's fix is minimal, symmetric across both code paths, matches the established cross-platform and cross-control convention for kern reapplication after a Text = assignment on UITextField, and is fully validated by:
- Two added device theories covering both reproduction paths.
- Gate run that confirmed the tests fail without the fix and pass with it.
- All
maui-prCI legs green. - Expert reviewer agent finding zero blockers, important issues, or nits.
The try-fix alternatives all introduce trade-offs (larger diff, divergent convention, refactor coupling, or unusual control flow) without any compensating reduction in risk or improvement in coverage. Picking pr over pr-plus-reviewer arbitrarily — they have identical diffs.
Final ranking
- pr ≈ pr-plus-reviewer (tied — identical diffs)
- try-fix-2 (closest alternative, but breaks convention)
- try-fix-3 (good idea, wrong PR)
- try-fix-4 (works but unidiomatic)
- try-fix-1 (most engineering, least proportional)
…PickerHandlerTests.iOS (#35419) <!-- Please let the below note in for people that find this PR --> > [!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](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Root Cause - PRs #34957 and #34974 each independently added an identical GetNativeCharacterSpacing(PickerHandler) helper method to PickerHandlerTests.iOS.cs at different locations in the file, so when the two PRs were combined the changes merged without a textual conflict and left two identical method definitions inside the PickerHandlerTests class, which the C# compiler rejected with error CS0111 ("type already defines a member with the same parameter types"). ### Description of Change - Removed the duplicate GetNativeCharacterSpacing(PickerHandler) method from PickerHandlerTests.iOS.cs, keeping a single definition of the helper so the Core.DeviceTests project compiles cleanly. ### Output | Before | After | |----------|----------| | <img src="https://github.com/user-attachments/assets/36b5a616-6567-4488-9cee-f456c13f8b60"> | <img src="https://github.com/user-attachments/assets/7f9d1c93-42e5-4d51-bd38-ac8e44fc1d55"> |
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!
Issue Details
Root Cause
Description of Change
Issues Fixed
Fixes #34971
Validated the behaviour in the following platforms
Output
Before.mov
After.mov