Skip to content

[iOS] Fix Picker CharacterSpacing ignored on initial load#34957

Merged
kubaflo merged 4 commits into
dotnet:inflight/currentfrom
SyedAbdulAzeemSF4852:fix/picker-initial-character-spacing
May 12, 2026
Merged

[iOS] Fix Picker CharacterSpacing ignored on initial load#34957
kubaflo merged 4 commits into
dotnet:inflight/currentfrom
SyedAbdulAzeemSF4852:fix/picker-initial-character-spacing

Conversation

@SyedAbdulAzeemSF4852

Copy link
Copy Markdown
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!

Issue Details

  • On iOS, a Picker does not apply CharacterSpacing to the selected item text during initial load — the text appears without spacing at first. However, if CharacterSpacing is set or updated after the control has already loaded, it applies correctly.

Root Cause

  • When the Picker handler initializes, CharacterSpacing is mapped before SelectedIndex, so by the time the spacing is applied there is no text yet — making it a no-op. Additionally, any programmatic SelectedIndex change afterwards overwrites the text as a plain string, wiping the spacing that was applied earlier.

Description of Change

  • Defer applying CharacterSpacing until after the view is fully loaded (so the text is already set), and re-apply it every time the picker text is updated.

Issues Fixed

Fixes #34955

Validated the behaviour in the following platforms

  • Windows
  • Android
  • iOS
  • Mac

Output

Before After
Before.mov
After.mov

@github-actions

github-actions Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34957

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34957"

@dotnet-policy-service dotnet-policy-service Bot added community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration labels Apr 14, 2026
@sheiksyedm sheiksyedm marked this pull request as ready for review April 14, 2026 12:31
Copilot AI review requested due to automatic review settings April 14, 2026 12:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes iOS/Mac Catalyst Picker so CharacterSpacing is applied on initial load and preserved when the selected item text is updated.

Changes:

  • Added iOS device tests validating initial CharacterSpacing application and preservation after SelectedIndex updates.
  • Reapplies CharacterSpacing whenever MauiPicker.UpdatePicker(...) updates the displayed text.
  • Defers CharacterSpacing mapping until the platform view is loaded (iOS handler mapping).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/Core/tests/DeviceTests/Handlers/Picker/PickerHandlerTests.iOS.cs Adds coverage for initial and post-selection-change CharacterSpacing behavior on iOS.
src/Core/src/Platform/iOS/PickerExtensions.cs Ensures UpdatePicker reapplies CharacterSpacing after updating Text/placeholder.
src/Core/src/Handlers/Picker/PickerHandler.iOS.cs Updates iOS mapper to apply CharacterSpacing after load; minor formatting change nearby.

Comment thread src/Core/src/Handlers/Picker/PickerHandler.iOS.cs
@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-win AI found a better alternative fix than the PR s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Apr 15, 2026

@kubaflo kubaflo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you please review the Ai's summary?

@SyedAbdulAzeemSF4852

Copy link
Copy Markdown
Contributor Author

Could you please review the Ai's summary?

@kubaflo , Reviewed the AI summary. The gate was reported as failed, but I verified locally that the test fails without the fix and passes with the fix applied.

Without_Fix With_Fix

Applied the suggested simplification by removing the OnLoaded deferral in MapCharacterSpacing and replacing it with a direct UpdateCharacterSpacing call.

Regarding the UpdatePickerFromPickerSource path — that regression (character spacing lost when user physically selects from the picker wheel) is tracked and fixed in #34974.

@dotnet dotnet deleted a comment from MauiBot Apr 22, 2026
@dotnet dotnet deleted a comment from MauiBot Apr 22, 2026
@kubaflo kubaflo added the s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation label Apr 22, 2026
@MauiBot MauiBot added s/agent-review-incomplete and removed s/agent-changes-requested AI agent recommends changes - found a better alternative or issues labels Apr 22, 2026
@dotnet dotnet deleted a comment from MauiBot Apr 22, 2026
@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues and removed s/agent-review-incomplete labels Apr 22, 2026
@kubaflo kubaflo dismissed MauiBot’s stale review May 2, 2026 19:26

Resetting for re-review

MauiBot
MauiBot previously requested changes May 2, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 Automated review — alternative fix proposed

The expert-reviewer evaluation compared the PR fix against #2 automatically generated candidates and selected try-fix-2 as the strongest fix.

Why: The PR's fix (adding UpdateCharacterSpacing inside UpdatePicker) fails because a recursive UpdatePicker call triggered by BindableProperty propagation overwrites the applied spacing. Try-fix-2 overrides MauiPicker.Text setter to self-apply stored CharacterSpacing on every text assignment, covering all paths (initial load, programmatic SelectedIndex change, user physical selection, EditingChanged events) without call-site coordination. Both gate-equivalent tests pass.

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-2`)
diff --git a/src/Core/src/Platform/iOS/MauiPicker.cs b/src/Core/src/Platform/iOS/MauiPicker.cs
index 06956ddc67..d1541a0aa9 100644
--- a/src/Core/src/Platform/iOS/MauiPicker.cs
+++ b/src/Core/src/Platform/iOS/MauiPicker.cs
@@ -11,6 +11,10 @@ namespace Microsoft.Maui.Platform
 	{
 		readonly HashSet<string> _enableActions;
 
+		// Stores character spacing so it can be re-applied when Text is set,
+		// since setting plain Text replaces AttributedText and clears the kern attribute.
+		internal double CharacterSpacing { get; set; }
+
 		public MauiPicker(UIPickerView? uIPickerView)
 		{
 			UIPickerView = uIPickerView;
@@ -22,6 +26,23 @@ namespace Microsoft.Maui.Platform
 		[UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")]
 		public UIPickerView? UIPickerView { get; set; }
 
+		public override string? Text
+		{
+			get => base.Text;
+			set
+			{
+				base.Text = value;
+				// Setting plain Text replaces AttributedText, stripping the kern attribute.
+				// Re-apply character spacing so it persists through any text change.
+				if (CharacterSpacing != 0)
+				{
+					var textAttr = AttributedText?.WithCharacterSpacing(CharacterSpacing);
+					if (textAttr != null)
+						AttributedText = textAttr;
+				}
+			}
+		}
+
 		public override bool CanPerform(Selector action, NSObject? withSender)
 			=> _enableActions.Contains(action.Name);
 	}
diff --git a/src/Core/src/Platform/iOS/PickerExtensions.cs b/src/Core/src/Platform/iOS/PickerExtensions.cs
index c2de04d1fd..f37490df2f 100644
--- a/src/Core/src/Platform/iOS/PickerExtensions.cs
+++ b/src/Core/src/Platform/iOS/PickerExtensions.cs
@@ -15,6 +15,19 @@ namespace Microsoft.Maui.Platform
 		public static void UpdateTextColor(this MauiPicker platformPicker, IPicker picker) =>
 			platformPicker.TextColor = picker.TextColor?.ToPlatform();
 
+		public static void UpdateCharacterSpacing(this MauiPicker platformPicker, IPicker picker)
+		{
+			// Store the spacing so the Text setter override can re-apply it on every text change.
+			platformPicker.CharacterSpacing = picker.CharacterSpacing;
+			// Apply to current AttributedText (handles runtime updates when text is already set).
+			var textAttr = platformPicker.AttributedText?.WithCharacterSpacing(picker.CharacterSpacing);
+			if (textAttr != null)
+				platformPicker.AttributedText = textAttr;
+			var placeholderAttr = platformPicker.AttributedPlaceholder?.WithCharacterSpacing(picker.CharacterSpacing);
+			if (placeholderAttr != null)
+				platformPicker.AttributedPlaceholder = placeholderAttr;
+		}
+
 		public static void UpdateSelectedIndex(this MauiPicker platformPicker, IPicker picker) =>
 			platformPicker.UpdatePicker(picker, picker.SelectedIndex);
 
diff --git a/src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt b/src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
index 46f10522b9..0e5f5ca61c 100644
--- a/src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
+++ b/src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
@@ -6,3 +6,6 @@ override Microsoft.Maui.Platform.MauiTextView.TextAlignment.get -> UIKit.UITextA
 override Microsoft.Maui.Platform.MauiTextView.TextAlignment.set -> void
 override Microsoft.Maui.Platform.MauiView.DidUpdateFocus(UIKit.UIFocusUpdateContext! context, UIKit.UIFocusAnimationCoordinator! coordinator) -> void
 static Microsoft.Maui.Handlers.DatePickerHandler.MapFlowDirection(Microsoft.Maui.Handlers.IDatePickerHandler! handler, Microsoft.Maui.IDatePicker! datePicker) -> void
+override Microsoft.Maui.Platform.MauiPicker.Text.get -> string?
+override Microsoft.Maui.Platform.MauiPicker.Text.set -> void
+static Microsoft.Maui.Platform.PickerExtensions.UpdateCharacterSpacing(this Microsoft.Maui.Platform.MauiPicker! platformPicker, Microsoft.Maui.IPicker! picker) -> void
diff --git a/src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt b/src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
index 46f10522b9..0e5f5ca61c 100644
--- a/src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
+++ b/src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
@@ -6,3 +6,6 @@ override Microsoft.Maui.Platform.MauiTextView.TextAlignment.get -> UIKit.UITextA
 override Microsoft.Maui.Platform.MauiTextView.TextAlignment.set -> void
 override Microsoft.Maui.Platform.MauiView.DidUpdateFocus(UIKit.UIFocusUpdateContext! context, UIKit.UIFocusAnimationCoordinator! coordinator) -> void
 static Microsoft.Maui.Handlers.DatePickerHandler.MapFlowDirection(Microsoft.Maui.Handlers.IDatePickerHandler! handler, Microsoft.Maui.IDatePicker! datePicker) -> void
+override Microsoft.Maui.Platform.MauiPicker.Text.get -> string?
+override Microsoft.Maui.Platform.MauiPicker.Text.set -> void
+static Microsoft.Maui.Platform.PickerExtensions.UpdateCharacterSpacing(this Microsoft.Maui.Platform.MauiPicker! platformPicker, Microsoft.Maui.IPicker! picker) -> void

@dotnet dotnet deleted a comment from MauiBot May 3, 2026
@kubaflo kubaflo dismissed MauiBot’s stale review May 3, 2026 12:45

Resetting for re-review

MauiBot
MauiBot previously requested changes May 3, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 Automated review — alternative fix proposed

The expert-reviewer evaluation compared the PR fix against #2 automatically generated candidates and selected try-fix-2 as the strongest fix.

Why: try-fix-2 introduces a SetPickerItemText atomic helper in PickerExtensions.cs that sets text and reapplies CharacterSpacing together, used at all three text-clobbering sites (UpdatePicker, UpdatePickerFromPickerSource, OnEditing). It passed all 2523 device tests with zero failures, follows the established MAUI iOS extension method pattern (matching DatePicker/TimePicker), makes no public API changes, and comprehensively fixes all paths where plain .Text assignment silently wipes AttributedText kerning — gaps that the original PR left open.

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-2`)
diff --git a/src/Core/src/Handlers/Picker/PickerHandler.iOS.cs b/src/Core/src/Handlers/Picker/PickerHandler.iOS.cs
index a54299d290..34f77a735b 100644
--- a/src/Core/src/Handlers/Picker/PickerHandler.iOS.cs
+++ b/src/Core/src/Handlers/Picker/PickerHandler.iOS.cs
@@ -255,7 +255,9 @@ namespace Microsoft.Maui.Handlers
 			if (VirtualView == null || PlatformView == null || pickerSource == null)
 				return;
 
-			PlatformView.Text = VirtualView.GetItem(pickerSource.SelectedIndex);
+			// Use SetPickerItemText to atomically set text with character spacing,
+			// preventing plain .Text assignment from silently dropping AttributedText kerning.
+			PlatformView.SetPickerItemText(VirtualView.GetItem(pickerSource.SelectedIndex), VirtualView.CharacterSpacing);
 			VirtualView.SelectedIndex = pickerSource.SelectedIndex;
 		}
 
@@ -423,7 +425,8 @@ 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);
+				// Use SetPickerItemText to preserve character spacing when resetting text.
+				platformView.SetPickerItemText(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..e6d36c0b27 100644
--- a/src/Core/src/Platform/iOS/PickerExtensions.cs
+++ b/src/Core/src/Platform/iOS/PickerExtensions.cs
@@ -36,18 +36,38 @@ namespace Microsoft.Maui.Platform
 			platformPicker.UpdateAttributedPlaceholder(new NSAttributedString(picker.Title ?? string.Empty, null, picker?.TitleColor?.ToPlatform()));
 		}
 
+		// Sets picker item text and applies character spacing atomically in one helper.
+		// Using a shared helper guarantees all code paths (UpdatePicker, UpdatePickerFromPickerSource,
+		// OnEditing) preserve character spacing - callers cannot accidentally skip the spacing step.
+		// Follows the established MAUI iOS pattern: set .Text first (UIKit synthesises AttributedText
+		// with font/color), then overlay KerningAdjustment via WithCharacterSpacing.
+		internal static void SetPickerItemText(this MauiPicker platformPicker, string? text, double characterSpacing)
+		{
+			platformPicker.Text = text;
+			if (characterSpacing != 0)
+			{
+				var textAttr = platformPicker.AttributedText?.WithCharacterSpacing(characterSpacing);
+				if (textAttr != null)
+					platformPicker.AttributedText = textAttr;
+			}
+		}
+
 		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.SetPickerItemText(picker.GetItem(selectedIndex), picker.CharacterSpacing);
 			}
 			else
 			{
 				platformPicker.Text = null;
 				platformPicker.UpdatePickerTitle(picker);
+				// Apply character spacing to placeholder when no item is selected
+				var phAttr = platformPicker.AttributedPlaceholder?.WithCharacterSpacing(picker.CharacterSpacing);
+				if (phAttr != null)
+					platformPicker.AttributedPlaceholder = phAttr;
 			}
 
 			var pickerView = platformPicker.UIPickerView;

@dotnet dotnet deleted a comment from MauiBot May 7, 2026
@kubaflo kubaflo dismissed MauiBot’s stale review May 7, 2026 23:22

Resetting for re-review

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 Automated review — alternative fix proposed

The expert-reviewer evaluation compared the PR fix against #4 automatically generated candidates and selected try-fix-4 as the strongest fix.

Why: try-fix-4 addresses the root cause (PickerHandler mapper ordering) via Mapper dictionary reorder + AppendToMapping for iOS/MacCatalyst, the idiomatic MAUI extension pattern. It passes both target device tests, removes the PR's stray blank line, and replaces the call inside PickerExtensions.UpdatePicker with a one-time mapper-level chain - yielding a smaller platform-extension footprint than the PR.

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-4`)
diff --git a/src/Core/src/Handlers/Picker/PickerHandler.cs b/src/Core/src/Handlers/Picker/PickerHandler.cs
index b5be3950c5..9badc89979 100644
--- a/src/Core/src/Handlers/Picker/PickerHandler.cs
+++ b/src/Core/src/Handlers/Picker/PickerHandler.cs
@@ -22,7 +22,6 @@ namespace Microsoft.Maui.Handlers
 #if __ANDROID__
 			[nameof(IView.IsEnabled)] = MapIsEnabled,
 #endif
-			[nameof(IPicker.CharacterSpacing)] = MapCharacterSpacing,
 			[nameof(IPicker.Font)] = MapFont,
 			[nameof(IPicker.SelectedIndex)] = MapSelectedIndex,
 			[nameof(IPicker.TextColor)] = MapTextColor,
@@ -31,6 +30,7 @@ namespace Microsoft.Maui.Handlers
 			[nameof(ITextAlignment.HorizontalTextAlignment)] = MapHorizontalTextAlignment,
 			[nameof(ITextAlignment.VerticalTextAlignment)] = MapVerticalTextAlignment,
 			[nameof(IPicker.Items)] = MapItems,
+			[nameof(IPicker.CharacterSpacing)] = MapCharacterSpacing,
 			[nameof(IPicker.IsOpen)] = MapIsOpen,
 		};
 
@@ -44,6 +44,14 @@ namespace Microsoft.Maui.Handlers
 #endif
 		};
 
+		static PickerHandler()
+		{
+#if __IOS__ || MACCATALYST
+			Mapper.AppendToMapping(nameof(IPicker.SelectedIndex), MapCharacterSpacing);
+			Mapper.AppendToMapping(nameof(IPicker.Items), MapCharacterSpacing);
+#endif
+		}
+
 		public PickerHandler() : base(Mapper, CommandMapper)
 		{
 		}
diff --git a/src/Core/tests/DeviceTests/Handlers/Picker/PickerHandlerTests.iOS.cs b/src/Core/tests/DeviceTests/Handlers/Picker/PickerHandlerTests.iOS.cs
index 16a438c766..45e8e9efe1 100644
--- a/src/Core/tests/DeviceTests/Handlers/Picker/PickerHandlerTests.iOS.cs
+++ b/src/Core/tests/DeviceTests/Handlers/Picker/PickerHandlerTests.iOS.cs
@@ -64,6 +64,55 @@ namespace Microsoft.Maui.DeviceTests
 			Assert.Equal(expectedValue, values.PlatformViewValue);
 		}
 
+		[Fact(DisplayName = "CharacterSpacing Initializes Correctly")]
+		public async Task CharacterSpacingInitializesCorrectly()
+		{
+			const double xplatCharacterSpacing = 4;
+
+			var picker = new PickerStub
+			{
+				Items = new[] { "Item 1", "Item 2", "Item 3" },
+				SelectedIndex = 1,
+				CharacterSpacing = xplatCharacterSpacing
+			};
+
+			var values = await GetValueAsync(picker, (handler) =>
+			{
+				return new
+				{
+					ViewValue = picker.CharacterSpacing,
+					PlatformViewValue = GetNativeCharacterSpacing(handler)
+				};
+			});
+
+			Assert.Equal(xplatCharacterSpacing, values.ViewValue);
+			Assert.Equal(xplatCharacterSpacing, values.PlatformViewValue);
+		}
+
+		[Fact(DisplayName = "CharacterSpacing Maintained After SelectedIndex Change")]
+		public async Task CharacterSpacingMaintainedAfterSelectedIndexChange()
+		{
+			const double xplatCharacterSpacing = 4;
+
+			var picker = new PickerStub
+			{
+				Items = new[] { "Item 1", "Item 2", "Item 3" },
+				SelectedIndex = 0,
+				CharacterSpacing = xplatCharacterSpacing
+			};
+
+			await SetValueAsync(picker, 2, (handler, value) =>
+			{
+				handler.VirtualView.SelectedIndex = value;
+				handler.UpdateValue(nameof(IPicker.SelectedIndex));
+			});
+
+			var nativeCharacterSpacing = await GetValueAsync(picker, (handler) =>
+				GetNativeCharacterSpacing(handler));
+
+			Assert.Equal(xplatCharacterSpacing, nativeCharacterSpacing);
+		}
+
 		MauiPicker GetNativePicker(PickerHandler pickerHandler) =>
 			pickerHandler.PlatformView;
 
@@ -110,6 +159,12 @@ namespace Microsoft.Maui.DeviceTests
 			return mauiPicker.TextColor;
 		}
 
+		double GetNativeCharacterSpacing(PickerHandler pickerHandler)
+		{
+			var mauiPicker = GetNativePicker(pickerHandler);
+			return mauiPicker.AttributedText.GetCharacterSpacing();
+		}
+
 		UIControlContentVerticalAlignment GetNativeVerticalTextAlignment(PickerHandler pickerHandler) =>
 			GetNativePicker(pickerHandler).VerticalAlignment;
 	}

@dotnet dotnet deleted a comment from MauiBot May 11, 2026
@MauiBot

MauiBot commented May 11, 2026

Copy link
Copy Markdown
Collaborator

🤖 AI Summary

👋 @SyedAbdulAzeemSF4852 — new AI review results are available. Please review the latest session below.

📊 Review Sessionfa1d2e7 · fix: remove unnecessary OnLoaded deferral in MapCharacterSpacing for iOS Picker · 2026-05-11 22:08 UTC
🚦 Gate — Test Before & After Fix

Gate Result: ✅ PASSED

Platform: IOS · Base: main · Merge base: f8cb875e

Test Without Fix (expect FAIL) With Fix (expect PASS)
📱 PickerHandlerTests (CharacterSpacingInitializesCorrectly, CharacterSpacingMaintainedAfterSelectedIndexChange) Category=Picker ✅ FAIL — 396s ✅ PASS — 228s
🔴 Without fix — 📱 PickerHandlerTests (CharacterSpacingInitializesCorrectly, CharacterSpacingMaintainedAfterSelectedIndexChange): FAIL ✅ · 396s

(truncated to last 15,000 chars)

6:04.787198-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Native View Bounding Box is not empty
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8017530] 2026-05-11 14:16:04.801449-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Test name: CharacterSpacing Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8019570] 2026-05-11 14:16:04.801776-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Exception messages: Assert.Equal() Failure: Values differ
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8019700] Expected: 4
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8019770] Actual:   0
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8022780] 2026-05-11 14:16:04.802046-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Exception stack traces:    at Microsoft.Maui.DeviceTests.PickerHandlerTests.CharacterSpacingInitializesCorrectly()
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8030050] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8030310] 2026-05-11 14:16:04.802181-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Execution time: 0.0102951
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8030490] 2026-05-11 14:16:04.802342-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Test trait name: Category
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8030540] 2026-05-11 14:16:04.802499-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]       value: Picker
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8030560] 2026-05-11 14:16:04.802708-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[FAIL] CharacterSpacing Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8030590] 2026-05-11 14:16:04.802822-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[FAIL] CharacterSpacing Initializes Correctly   Test name: CharacterSpacing Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8030620]    Assembly:  [Microsoft.Maui.Core.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8032740] 2026-05-11 14:16:04.802942-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Exception messages: Assert.Equal() Failure: Values differ
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8032910] Expected: 4
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8033000] Actual:   0   Exception stack traces:    at Microsoft.Maui.DeviceTests.PickerHandlerTests.CharacterSpacingInitializesCorrectly()
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8033050] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8033160]    Execution time: 0.0102951
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8033210] 2026-05-11 14:16:04.803071-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Test trait name: Category
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8033270]       value: Picker
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8151450] 2026-05-11 14:16:04.814685-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] InputTransparencyInitializesCorrectly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8183620] 2026-05-11 14:16:04.818123-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] InputTransparencyInitializesCorrectly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8271090] 2026-05-11 14:16:04.826816-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Test name: CharacterSpacing Maintained After SelectedIndex Change
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8271950] 2026-05-11 14:16:04.826991-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Exception messages: Assert.Equal() Failure: Values differ
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8272090] Expected: 4
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8272170] Actual:   0
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8273460] 2026-05-11 14:16:04.827148-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Exception stack traces:    at Microsoft.Maui.DeviceTests.PickerHandlerTests.CharacterSpacingMaintainedAfterSelectedIndexChange()
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8273760] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8274370] 2026-05-11 14:16:04.827277-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Execution time: 0.0080287
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8275360] 2026-05-11 14:16:04.827391-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Test trait name: Category
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8276300] 2026-05-11 14:16:04.827473-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]       value: Picker
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8278790] 2026-05-11 14:16:04.827564-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[FAIL] CharacterSpacing Maintained After SelectedIndex Change
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8278920] 2026-05-11 14:16:04.827658-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[FAIL] CharacterSpacing Maintained After SelectedIndex Change   Test name: CharacterSpacing Maintained After SelectedIndex Change
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8278980]    Assembly:  [Microsoft.Maui.Core.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8279580] 2026-05-11 14:16:04.827780-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Exception messages: Assert.Equal() Failure: Values differ
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8280040] Expected: 4
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8280160] Actual:   0   Exception stack traces:    at Microsoft.Maui.DeviceTests.PickerHandlerTests.CharacterSpacingMaintainedAfterSelectedIndexChange()
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8280200] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8280260] 2026-05-11 14:16:04.827887-0700 Microsoft.Maui.Core.DeviceTests[6811:44894]    Execution time: 0.0080287
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8280300]    Test trait name: Category
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:04.8280330]       value: Picker
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.0597210] 2026-05-11 14:16:05.059428-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Setting Semantic Description makes element accessible
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.0701510] 2026-05-11 14:16:05.069744-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] FlowDirection is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.0732240] 2026-05-11 14:16:05.072963-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] FlowDirection is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.3496810] 2026-05-11 14:16:05.349292-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] ContainerView Adds And Removes
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.3536760] 2026-05-11 14:16:05.353401-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Transformation Calculated Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.3574320] 2026-05-11 14:16:05.357126-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Automation Id is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.3613730] 2026-05-11 14:16:05.360920-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Updating Text Does Not Affect HorizontalTextAlignment
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.3717480] 2026-05-11 14:16:05.371421-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Updating Text Does Not Affect HorizontalTextAlignment
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.3794550] 2026-05-11 14:16:05.379147-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Text Color Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.3841510] 2026-05-11 14:16:05.383899-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] ContainerView Remains If Shadow Mapper Runs Again
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.3889410] 2026-05-11 14:16:05.388676-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Native View Bounds are not empty
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.3927210] 2026-05-11 14:16:05.392434-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Native View Bounds are not empty
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.3954810] 2026-05-11 14:16:05.395183-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Native View Bounds are not empty
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.6287830] 2026-05-11 14:16:05.628499-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Semantic Heading is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.6622140] 2026-05-11 14:16:05.661963-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Background Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.6849670] 2026-05-11 14:16:05.684634-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Background Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7108910] 2026-05-11 14:16:05.710597-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Background Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7243860] 2026-05-11 14:16:05.724112-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Semantic Description is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7288060] 2026-05-11 14:16:05.728558-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7317530] 2026-05-11 14:16:05.731428-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7340620] 2026-05-11 14:16:05.733793-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7365490] 2026-05-11 14:16:05.736161-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7441400] 2026-05-11 14:16:05.741586-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] 	[PASS] Opacity is set correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7470580] 2026-05-11 14:16:05.743681-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] Microsoft.Maui.DeviceTests.PickerHandlerTests 1.3181431 ms
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7526460] 2026-05-11 14:16:05.752357-0700 Microsoft.Maui.Core.DeviceTests[6811:45374] Failed tests:
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7594150] 2026-05-11 14:16:05.753179-0700 Microsoft.Maui.Core.DeviceTests[6811:45374] 1) 	[FAIL] CharacterSpacing Initializes Correctly   Test name: CharacterSpacing Initializes Correctly
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7594580]    Assembly:  [Microsoft.Maui.Core.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7594660] 2026-05-11 14:16:05.758634-0700 Microsoft.Maui.Core.DeviceTests[6811:45374]    Exception messages: Assert.Equal() Failure: Values differ
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7594690] Expected: 4
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7594750] Actual:   0   Exception stack traces:    at Microsoft.Maui.DeviceTests.PickerHandlerTests.CharacterSpacingInitializesCorrectly()
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7594780] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7594800]    Execution time: 0.0102951
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7594830] 2026-05-11 14:16:05.758993-0700 Microsoft.Maui.Core.DeviceTests[6811:45374]    Test trait name: Category
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7594910]       value: Picker
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7594940] 2026-05-11 14:16:05.759131-0700 Microsoft.Maui.Core.DeviceTests[6811:45374] 2) 	[FAIL] CharacterSpacing Maintained After SelectedIndex Change   Test name: CharacterSpacing Maintained After SelectedIndex Change
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7595010]    Assembly:  [Microsoft.Maui.Core.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7595040] 2026-05-11 14:16:05.759256-0700 Microsoft.Maui.Core.DeviceTests[6811:45374]    Exception messages: Assert.Equal() Failure: Values differ
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7595070] Expected: 4
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7595090] Actual:   0   Exception stack traces:    at Microsoft.Maui.DeviceTests.PickerHandlerTests.CharacterSpacingMaintainedAfterSelectedIndexChange()
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7595120] --- End of stack trace from previous location ---
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7595480] 2026-05-11 14:16:05.759379-0700 Microsoft.Maui.Core.DeviceTests[6811:45374]    Execution time: 0.0080287
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7595520]    Test trait name: Category
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7595550]       value: Picker
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7603000] 2026-05-11 14:16:05.760058-0700 Microsoft.Maui.Core.DeviceTests[6811:45374] Tests run: 91 Passed: 88 Inconclusive: 0 Failed: 2 Ignored: 1
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7779600] 2026-05-11 14:16:05.777528-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] Xml file was written to the provided writer.
�[40m�[37mdbug�[39m�[22m�[49m: [14:16:05.7781100] 2026-05-11 14:16:05.777871-0700 Microsoft.Maui.Core.DeviceTests[6811:44894] Tests run: 1168 Passed: 88 Inconclusive: 0 Failed: 2 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": "LJHLFCVGXC-1",
        "exitCode": 1,
        "exitCodeName": "TESTS_FAILED",
        "platform": "apple",
        "device": "iPhone 11 Pro",
        "deviceOsVersion": "26.0",
        "files": [
          {
            "name": "test-ios-simulator-64_26.0-0027153A-1282-4BC3-B7D8-EE0F5555AF08.log",
            "type": "executionlog"
          },
          {
            "name": "list-ios-simulator-64_26.0-20260511_141529.log",
            "type": "devicelist"
          },
          {
            "name": "test-ios-simulator-64_26.0-20260511_141536.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_141536.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 (CharacterSpacingInitializesCorrectly, CharacterSpacingMaintainedAfterSelectedIndexChange): PASS ✅ · 228s

(truncated to last 15,000 chars)

pplication/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : monoeg_g_log
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1602260] 	0x10c686848 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_aot_module
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1602350] 	0x10c760618 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_load_from
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1602390] 	0x10c760134 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_open
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1602430] 	0x10c761454 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_open
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1613290] 	0x10c2cdddc - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libxamarin-dotnet.dylib : xamarin_assembly_preload_hook
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1613520] 	0x10c762470 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : invoke_assembly_preload_hook
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1613600] 	0x10c75f3f8 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_byname
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1613860] 	0x10c6900b0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_image
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1613940] 	0x10c6867e0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_aot_module
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1613990] 	0x10c760618 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_load_from
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1614040] 	0x10c760134 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_open
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1614180] 	0x10c761454 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_open
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1614250] 	0x10c2cdddc - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libxamarin-dotnet.dylib : xamarin_assembly_preload_hook
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1614300] 	0x10c762470 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : invoke_assembly_preload_hook
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1614340] 	0x10c75f3f8 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_byname
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1614460] 	0x10c6900b0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_image
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1614510] 	0x10c6867e0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_aot_module
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1614550] 	0x10c760618 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_load_from
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1614640] 	0x10c760134 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_open
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1615230] 	0x10c761454 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_open
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1615590] 	0x10c2cdddc - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libxamarin-dotnet.dylib : xamarin_assembly_preload_hook
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1615660] 	0x10c762470 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : invoke_assembly_preload_hook
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1615720] 	0x10c75f3f8 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_assembly_request_byname
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1615970] 	0x10c6900b0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_image
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1616060] 	0x10c6867e0 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : load_aot_module
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1616100] 	0x10c68afac - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_aot_get_method
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1616140] 	0x10c60ff3c - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_jit_compile_method_with_opt
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1616230] 	0x10c60dcac - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_jit_runtime_invoke
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1617830] 	0x10c7ce910 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_runtime_invoke_checked
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1618050] 	0x10c781818 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : create_exception_two_strings
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1618180] 	0x10c78159c - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_exception_from_name_two_strings_checked
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1618240] 	0x10c75b96c - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_runtime_init_checked
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1618340] 	0x10c60d63c - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mini_init
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1618400] 	0x10c664d1c - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libmonosgen-2.0.dylib : mono_jit_init
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1618490] 	0x10c2cd014 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libxamarin-dotnet.dylib : xamarin_bridge_initialize
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.1618540] 	0x10c2ce1e8 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/libxamarin-dotnet.dylib : xamarin_main
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2285680] 	0x1071f9610 - /Users/cloudtest/Library/Developer/CoreSimulator/Devices/0027153A-1282-4BC3-B7D8-EE0F5555AF08/data/Containers/Bundle/Application/72E75E9C-9D33-4C42-BF6A-8C67646C3A76/Microsoft.Maui.Core.DeviceTests.app/Microsoft.Maui.Core.DeviceTests : main
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2285930] 	0x10be953d0 - Unknown
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2286010] 	0x10bfcfda4 - Unknown
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2286060]
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2286170] =================================================================
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2286220] 	Basic Fault Address Reporting
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2286270] =================================================================
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2286430] Memory around native instruction pointer (0x10c1d088c):0x10c1d087c  c0 03 5f d6 c0 03 5f d6 10 29 80 d2 01 10 00 d4  .._..._..)......
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2286490] 0x10c1d088c  e3 00 00 54 fd 7b bf a9 fd 03 00 91 16 e3 ff 97  ...T.{..........
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2287390] 0x10c1d089c  bf 03 00 91 fd 7b c1 a8 c0 03 5f d6 c0 03 5f d6  .....{...._..._.
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2287630] 0x10c1d08ac  70 0a 80 d2 01 10 00 d4 e3 00 00 54 fd 7b bf a9  p..........T.{..
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2287700]
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2287750] =================================================================
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2287800] 	Managed Stacktrace:
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2287840] =================================================================
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2287880] 	  at <unknown> <0xffffffff>
�[40m�[37mdbug�[39m�[22m�[49m: [14:19:25.2287920] =================================================================
�[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": "LJHLFCVGXC-1",
        "exitCode": 0,
        "exitCodeName": "SUCCESS",
        "platform": "apple",
        "device": "iPhone 11 Pro",
        "deviceOsVersion": "26.0",
        "files": [
          {
            "name": "test-ios-simulator-64_26.0-0027153A-1282-4BC3-B7D8-EE0F5555AF08.log",
            "type": "executionlog"
          },
          {
            "name": "list-ios-simulator-64_26.0-20260511_141917.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.cs
  • src/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

Issue: #34955 - [iOS] Picker ignores CharacterSpacing on initial load
PR: #34957 - [iOS] Fix Picker CharacterSpacing ignored on initial load
Platforms Affected: iOS / MacCatalyst
Files Changed: 2 implementation, 1 test

Key Findings

  • Root cause: in the PickerHandler mapper (PickerHandler.cs:25-27), CharacterSpacing is mapped BEFORE SelectedIndex. At initial mapping the UITextField.Text is still empty/null, so UpdateCharacterSpacing (which reads AttributedText?.WithCharacterSpacing(...)) is a no-op — the resulting AttributedText is null so nothing is applied.
  • Secondary issue: PickerExtensions.UpdatePicker (called from MapSelectedIndex and UpdatePickerFromPickerSource → SelectedIndex setter) writes platformPicker.Text = ... as a plain string. Assigning UITextField.Text clears any attributed string the field previously had, so once the user changes selection the spacing is wiped.
  • PR fix: a single functional change — add platformPicker.UpdateCharacterSpacing(picker); immediately after the Text assignment inside UpdatePicker. This guarantees CharacterSpacing is re-applied every time text changes, covering both initial load and subsequent SelectedIndex changes.
  • Cosmetic change: a blank line added in PickerHandler.iOS.cs UpdatePickerFromPickerSource (no functional impact).
  • Tests: two new device tests on iOS — CharacterSpacingInitializesCorrectly (covers initial load) and CharacterSpacingMaintainedAfterSelectedIndexChange (covers selection update). Also adds a GetNativeCharacterSpacing helper reading from mauiPicker.AttributedText.GetCharacterSpacing().
  • Mapper order alternative: reorder mapper to put CharacterSpacing after SelectedIndex. Would fix initial load but NOT subsequent SelectedIndex changes (since Text is overwritten with a plain string). So PR's approach is more complete.
  • Edge case: UpdatePicker already handles selectedIndex == -1 by setting Text = null and calling UpdatePickerTitle — the new UpdateCharacterSpacing call still runs, but WithCharacterSpacing is a no-op when AttributedText is null, so no regression.
  • Edge case: UpdateCharacterSpacing also touches AttributedPlaceholder. Calling it after UpdatePickerTitle (which sets the placeholder) is correct ordering.

Code Review Summary

Verdict: LGTM
Confidence: high
Errors: 0 | Warnings: 1 | Suggestions: 2

Key code review findings:

  • ⚠️ PickerHandler.iOS.cs:259 — Added blank line is purely cosmetic / no functional impact; harmless but creates churn in diff. Consider removing for a cleaner diff.
  • 💡 PickerExtensions.cs:53UpdateCharacterSpacing is now called unconditionally even on the selectedIndex == -1 path (Text set to null). It's a no-op there because AttributedText is null, but ordering it inside the if/else branch (only when Text was actually set) would be marginally clearer. Not a correctness issue.
  • 💡 The PR does not adjust the mapper order. A defense-in-depth alternative would reorder so SelectedIndex (and thus initial Text assignment) is mapped BEFORE CharacterSpacing, in addition to the current re-apply approach. PR's approach alone is sufficient.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #34957 Re-apply UpdateCharacterSpacing inside PickerExtensions.UpdatePicker after Text is set ✅ PASSED (Gate) PickerHandler.iOS.cs, PickerExtensions.cs Original PR fix; covers both initial load and SelectedIndex change

🔧 Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result (predicted) Files Changed Notes
1 try-fix-1 (claude-opus-4.6, Handler Mapper) Reorder PickerHandler.Mapper so CharacterSpacing is registered AFTER SelectedIndex/Items — no functional change to PickerExtensions ❌ PARTIAL (1/2): test 1 PASS, test 2 FAIL — mapper order only affects initial bulk map, not later UpdateValue("SelectedIndex") calls which still overwrite Text as plain string PickerHandler.cs Insufficient by itself; would still need PR's re-apply for the regression-after-selection case
2 try-fix-2 (claude-sonnet-4.6, Logic & iOS Platform) Replace the Text = assignment in UpdatePicker with AttributedText = new NSAttributedString(text).WithCharacterSpacing(picker.CharacterSpacing) — make AttributedText the authoritative state ✅ PASS (2/2): every UpdatePicker rebuilds AttributedText with kerning baked in PickerExtensions.cs Slightly different mental model from rest of codebase; requires guarding for null WithCharacterSpacing return; loses the UpdateCharacterSpacing extension reuse
3 try-fix-3 (gpt-5.3-codex, Regression Prevention) Extract SetTextWithCharacterSpacing(this MauiPicker, IPicker, string?) helper and use it at THREE sites: UpdatePicker (2 spots), UpdatePickerFromPickerSource, and MauiPickerProxy.OnEditing ✅ PASS (2/2) + closes "Done on already-selected row" adjacent regression flagged by expert reviewer PickerExtensions.cs, PickerHandler.iOS.cs Broadest scope; addresses adjacent regression sites; matches expert reviewer's recommendation
4 try-fix-4 (gpt-5.4, Cross-Platform Consistency) Mirror DatePicker/TimePicker pattern: add UpdateCharacterSpacing at END of UpdatePicker (after pickerView.Select) AND change iOS MapCharacterSpacing to delegate to UpdatePicker ✅ PASS (2/2) PickerExtensions.cs, PickerHandler.iOS.cs Functionally converges with PR; placement at end matches sibling handlers; mapper delegation is minor extra churn
PR PR #34957 Add platformPicker.UpdateCharacterSpacing(picker); mid-UpdatePicker after Text/Title is set ✅ PASSED (Gate-verified) PickerExtensions.cs, PickerHandler.iOS.cs (cosmetic blank line) Minimal, surgical; covers reported regression but not the "Done on already-selected row" adjacent case

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 2 No Mapper reorder alone is insufficient; converges on the PR's approach for completeness
claude-sonnet-4.6 2 No AttributedText-first works but is stylistically isolated; PR's pattern is more idiomatic for this codebase
gpt-5.3-codex 2 Yes Add a SetTextWithCharacterSpacing helper used at all three Text-assignment sites — addresses regression-prevention dimension and the expert reviewer's "Done on same row" finding
gpt-5.4 2 No Final shape essentially matches PR; only the call position (end of UpdatePicker vs. mid-method) differs cosmetically

Exhausted: Yes — all four dimensions explored; remaining variation is purely cosmetic/placement.

Selected Fix: try-fix-3 (Helper extraction) — strictly broader correctness than PR's fix because it covers the "user taps Done on already-selected row" adjacent regression that the expert reviewer independently flagged. All other candidates either underperform (try-fix-1) or converge with the PR (try-fix-2, try-fix-4).

Environment Note

iOS device tests for each candidate were NOT executed inside try-fix (env constraint: 4 × ~30 min on macOS simulator queue is impractical inside this autonomous review). The Gate phase already verified PR's diff passes both new device tests on a real simulator. Predicted PASS/FAIL for each candidate is derived from code-path analysis against the deterministic test expectations:

  • Test 1 asserts mauiPicker.AttributedText.GetCharacterSpacing() == 4 after initial property mapping with CharacterSpacing=4, SelectedIndex=1.
  • Test 2 asserts the same after handler.UpdateValue("SelectedIndex") switches index from 0 → 2.

📋 Report — Final Recommendation

PR #34957 — Comparative Report

Candidates Evaluated

Candidate Approach Predicted Test Result Scope Quality Signal
pr Add UpdateCharacterSpacing(picker) inside PickerExtensions.UpdatePicker after Text/Title ✅ PASS (Gate verified on iOS simulator) Minimal — 2 files (1 functional + 1 cosmetic) LGTM from expert reviewer; correct for the reported regression
pr-plus-reviewer PR + (a) add PlatformView.UpdateCharacterSpacing(VirtualView) in UpdatePickerFromPickerSource after Text is set, (b) drop cosmetic blank line, (c) optional analogous call in MauiPickerProxy.OnEditing ✅ PASS — and additionally closes the "Done tapped on already-selected row" gap the reviewer flagged Small delta on top of PR (2-3 lines) Best correctness coverage; preserves Gate-validated core fix
try-fix-1 Reorder PickerHandler.Mapper so CharacterSpacing comes after SelectedIndex/Items ❌ PARTIAL — fixes test 1 (initial load) but FAILS test 2 (SelectedIndex change) because mapper order does not influence subsequent UpdateValue("SelectedIndex") calls that still overwrite Text as a plain string 1 file Insufficient by itself
try-fix-2 Assign AttributedText = NSAttributedString.WithCharacterSpacing(...) instead of Text = inside UpdatePicker ✅ PASS (both) 1 file Idiomatically isolated; AttributedText-first pattern is not used by sibling DatePicker/TimePicker extensions; minor null-handling complexity
try-fix-3 Extract SetTextWithCharacterSpacing helper; use at UpdatePicker (×2), UpdatePickerFromPickerSource, MauiPickerProxy.OnEditing ✅ PASS (both) + closes Done-on-same-row and OnEditing-typing-reset regression sites 2 files; new internal helper Strongest defense-in-depth; widest scope change
try-fix-4 Add UpdateCharacterSpacing at end of UpdatePicker AND route MapCharacterSpacing through UpdatePicker for consistency with DatePicker/TimePicker ✅ PASS (both) 2 files Largely converges with PR; differences are cosmetic (call position, mapper delegation)

Ranking Rules Applied

  • Candidates that fail regression tests rank lower → try-fix-1 is ranked last.
  • Among passing candidates, prefer broader correctness (closes adjacent regression sites) and least invasive delta from a Gate-validated baseline.

Winner: pr-plus-reviewer

Rationale:

  1. Inherits the Gate-validated core fix — the PR's single-line addition in PickerExtensions.UpdatePicker is verified to pass the two new iOS device tests on a real simulator. No risk of regressing the validated path.
  2. Closes the adjacent regression that the maui-expert-reviewer independently identified at PickerHandler.iOS.cs:258 (UpdatePickerFromPickerSource): when the user taps "Done" on the already-selected row, VirtualView.SelectedIndex = pickerSource.SelectedIndex is a no-op assignment that does NOT fire the mapper, so the raw PlatformView.Text = ... assignment on the line above silently wipes the AttributedText (and therefore CharacterSpacing). Adding PlatformView.UpdateCharacterSpacing(VirtualView) right after the Text assignment closes this gap.
  3. Smallest delta over PR — 2-3 additional lines in one file, plus removing the cosmetic blank-line churn that the reviewer flagged.
  4. Outperforms try-fix-1 trivially (try-fix-1 fails test 2).
  5. Outperforms try-fix-2 stylistically: try-fix-2's AttributedText-first pattern is not used by any sibling iOS picker extension (DatePicker/TimePicker use the Text-then-UpdateCharacterSpacing pattern); pr-plus-reviewer keeps the codebase pattern consistent.
  6. Outperforms try-fix-3 in invasiveness: try-fix-3 introduces a new internal helper and refactors three call sites including OnEditing. While defensible, the OnEditing path is far rarer than the UpdatePickerFromPickerSource path and not implicated by the reported bug. pr-plus-reviewer takes the same correctness win on the high-value site without the helper-extraction scope.
  7. Outperforms try-fix-4 in clarity: try-fix-4 routes MapCharacterSpacing through UpdatePicker, which couples two independent mapper concerns. pr-plus-reviewer keeps MapCharacterSpacing simple.

Recommended Action for the PR Author

Apply the following on top of the current PR:

 void UpdatePickerFromPickerSource(PickerSource? pickerSource)
 {
     if (VirtualView == null || PlatformView == null || pickerSource == null)
         return;

     PlatformView.Text = VirtualView.GetItem(pickerSource.SelectedIndex);
-
+    PlatformView.UpdateCharacterSpacing(VirtualView);
     VirtualView.SelectedIndex = pickerSource.SelectedIndex;
 }

(Drop the stray blank line, add the UpdateCharacterSpacing call.)

Optionally add a regression test for the Done-on-already-selected-row scenario.

Final Recommendation

Approve the PR with the small follow-up applied (pr-plus-reviewer). The PR's submitted fix is correct and Gate-passing on its own; the reviewer delta is a strict improvement that prevents an immediately-adjacent regression.


@MauiBot MauiBot added s/agent-review-incomplete and removed s/agent-changes-requested AI agent recommends changes - found a better alternative or issues labels May 11, 2026
@kubaflo kubaflo changed the base branch from main to inflight/current May 12, 2026 09:39
@kubaflo kubaflo merged commit 6fb1a71 into dotnet:inflight/current May 12, 2026
2 of 3 checks passed
@github-actions github-actions Bot added this to the .NET 10 SR7 milestone May 12, 2026
kubaflo pushed a commit that referenced this pull request May 13, 2026
…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">
|
@kubaflo kubaflo added s/agent-approved AI agent recommends approval - PR fix is correct and optimal s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) and removed s/agent-review-incomplete labels May 20, 2026
PureWeen pushed a commit that referenced this pull request Jun 2, 2026
<!-- 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!

### Issue Details

- On iOS, a Picker does not apply CharacterSpacing to the selected item
text during initial load — the text appears without spacing at first.
However, if CharacterSpacing is set or updated after the control has
already loaded, it applies correctly.

### Root Cause
- When the Picker handler initializes, CharacterSpacing is mapped before
SelectedIndex, so by the time the spacing is applied there is no text
yet — making it a no-op. Additionally, any programmatic SelectedIndex
change afterwards overwrites the text as a plain string, wiping the
spacing that was applied earlier.

### Description of Change

- Defer applying CharacterSpacing until after the view is fully loaded
(so the text is already set), and re-apply it every time the picker text
is updated.


### Issues Fixed
Fixes #34955

### Validated the behaviour in the following platforms

- [ ] Windows
- [ ] Android
- [x] iOS
- [x] Mac

### Output
| Before | After 
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/348cea91-902e-41e1-af15-4b9b9f442ce3">
| <video
src="https://github.com/user-attachments/assets/711765e3-66a2-43bf-ac65-287254df22d3">
|

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
PureWeen pushed a commit that referenced this pull request Jun 2, 2026
…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">
|
PureWeen pushed a commit that referenced this pull request Jun 11, 2026
<!-- 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!

### Issue Details

- On iOS, a Picker does not apply CharacterSpacing to the selected item
text during initial load — the text appears without spacing at first.
However, if CharacterSpacing is set or updated after the control has
already loaded, it applies correctly.

### Root Cause
- When the Picker handler initializes, CharacterSpacing is mapped before
SelectedIndex, so by the time the spacing is applied there is no text
yet — making it a no-op. Additionally, any programmatic SelectedIndex
change afterwards overwrites the text as a plain string, wiping the
spacing that was applied earlier.

### Description of Change

- Defer applying CharacterSpacing until after the view is fully loaded
(so the text is already set), and re-apply it every time the picker text
is updated.


### Issues Fixed
Fixes #34955

### Validated the behaviour in the following platforms

- [ ] Windows
- [ ] Android
- [x] iOS
- [x] Mac

### Output
| Before | After 
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/348cea91-902e-41e1-af15-4b9b9f442ce3">
| <video
src="https://github.com/user-attachments/assets/711765e3-66a2-43bf-ac65-287254df22d3">
|

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
PureWeen pushed a commit that referenced this pull request Jun 11, 2026
…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">
|
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/ios s/agent-approved AI agent recommends approval - PR fix is correct and optimal s/agent-fix-win AI found a better alternative fix than the PR s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[iOS] Picker ignores CharacterSpacing on initial load

6 participants